error C4996: 'sprintf': This function or variable may be unsafe.
Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
緩衝區溢出風險:`sprintf` 不檢查目標緩衝區大小,格式化字符串超過緩衝區會覆蓋相鄰內存。
char buf[10];
sprintf(buf, "This string is way too long for the buffer"); // ❌ 溢出
// 覆蓋返回地址 → 攻擊者可控制程序流 → 任意代碼執行
#define _CRT_SECURE_NO_WARNINGS
// 預處理階段定義宏
// CRT 头文件中:
// #ifndef _CRT_SECURE_NO_WARNINGS
// #pragma deprecated(sprintf) // 產生 C4996
// #endif
// 定義後跳過 deprecated 標記,編譯器不再報警
| 策略 | 適用場景 | 優缺點 |
|---|---|---|
| 定義宏抑制警告 | 快速移植舊代碼、臨時調試 | ⚠️ 掩蓋風險,不解決根本問題 |
| 改用 sprintf_s | Windows 平台新代碼 | ✅ 安全,需傳緩衝區大小 |
| 改用 snprintf (C99/C++11) | 跨平台代碼 | ✅ 標準、安全、返回寫入長度 |
char buf[100];
// sprintf_s (MSVC)
sprintf_s(buf, sizeof(buf), "Value: %d", 42); // 參數2: 緩衝區大小(字節)
// snprintf (標準 C99)
snprintf(buf, sizeof(buf), "Value: %d", 42); // 參數2: 最大寫入字節數(含\0)
// 返回值: 實際需要寫入的字符數(不含\0),若 >= size 發生截斷
#if defined(_MSC_VER)
#define SAFE_SPRINTF(buf, size, fmt, ...) sprintf_s(buf, size, fmt, __VA_ARGS__)
#else
#define SAFE_SPRINTF(buf, size, fmt, ...) snprintf(buf, size, fmt, __VA_ARGS__)
#endif
// 使用
SAFE_SPRINTF(buf, sizeof(buf), "Hello %s", name);
緩衝區溢出是 C/C++ 歷史上最大安全漏洞來源。多輸入幾個字符(`_s`、`size`),少無數個 CVE。
理解原理,選擇標準安全函數,從源頭消除隱患。