[英]C++ 'strcpy' gives a Warning (C4996)
我收到此警告,但所有功能都正常工作。
這到底是什么意思?
'strcpy': This function or variable may be unsafe.
Consider using strcpy_s instead. To disable deprecation,
use _CRT_SECURE_NO_WARNINGS. See online help for details.
此函數 (strcpy) 被認為是不安全的,因為沒有邊界檢查,並且可能導致緩沖區溢出。 (實際上 strcpy 因溢出漏洞而臭名昭著,所有程序員都避免使用它——或者至少應該避免它)。 建議是使用考慮目標緩沖區大小的安全函數以避免溢出。 您也可以使用 strncpy (但要小心!)。 您的代碼沒有問題,即函數將按您說的方式運行,但嘗試提供一個大於目標緩沖區的緩沖區作為輸入。 該函數將溢出目標緩沖區。 檢查這也鏈接文本
雖然 strcpy 是一個常見的字符串函數,但它一直是軟件中許多錯誤和安全漏洞的來源(由於緩沖區溢出很容易)。
微軟為了促進更安全的 C 和 C++ 編碼,為危險的字符串方法提供了一套替換函數。 通常,它們的原始名稱后跟 _s。 因此,根據警告中的建議,strcpy 的 Microsoft 安全版本是 strcpy_s。 請注意,這是 Microsoft 的特定功能,它並非無處不在。
你有幾個選擇。
我通常做#3。
由於您正在編寫 C++,因此正確的解決方案是在可能的情況下從您的代碼中禁止 C 風格的char*
字符串,並用std::string
(或其他適當的字符串類型)替換它們。
不要使用功能,如strcpy
或strcpy_s
或strncpy
。 使用string
類的復制構造函數或賦值運算符。 或者,如果您確實需要復制緩沖區,請使用std::copy
。
由於 VC++ 8 strcpy()
和大量其他函數被認為是不安全的,因為它們沒有邊界檢查,如果誤用可能會導致緩沖區溢出。
您有兩個選擇:
_CRT_SECURE_NO_WARNINGS
,這將使警告消失。實際上有一種方法可以避免這個警告,仍然使用 strcpy,並且是安全的:
您可以啟用安全模板重載。 他們將(如果可能)通過使用模板化重載捕獲它們來推斷使用的緩沖區的長度。 為什么在 Visual C++ 中默認情況下沒有啟用這對我來說是個謎。
該警告基本上是在通知您 strcpy 已被棄用,因為復制字符串直到\\0
很容易導致令人討厭的問題(緩沖區溢出)。 strcpy 仍然存在並且有效的原因是它是標准庫遺留的一部分,但您真的應該考慮使用 str*_s 或 strn* 函數(它們不完全依賴於查找終止\\0
)。
由於緩沖區溢出不僅與安全問題有關,而且與相對難以跟蹤和修復的錯誤有關,因此使用普通的 str* 函數不僅通常不受歡迎,而且可能導致人們拒絕您的代碼,因為您的代碼本質上是不安全的。
更多詳情: http : //www.safercode.com/blog/2008/11/04/unsafe-functions-in-c-and-their-safer-replacements-strings-part-i.html
#pragma warning(disable: 4996)
在代碼的第一行使用上面的代碼。
如果您已經查看了使用 C++ 純粹技術與不用擔心的利弊,因為您“知道”您的字符串將以零結尾,那么您還可以在 msvc 中禁用警告,這類事情:
#ifdef _MSC_VER
// 4231: nonstandard extension used : 'extern' before template explicit instantiation
// 4250: dominance
// 4251: member needs to have dll-interface
// 4275: base needs to have dll-interface
// 4660: explicitly instantiating a class that's already implicitly instantiated
// 4661: no suitable definition provided for explicit template instantiation request
// 4786: identifer was truncated in debug information
// 4355: 'this' : used in base member initializer list
// 4910: '__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation
# pragma warning(disable: 4231 4250 4251 4275 4660 4661 4786 4355 4910)
#endif
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
在文件的頂部為我工作(基於其他 SO 用戶的回答......但我找不到引用他/她)
使用安全模板重載或定義包裝函數不適用於動態分配的緩沖區,因此這種嘗試是徒勞的。
修改源以使用安全替換,或者只是忽略它。
如果代碼是自己寫的,最好把strcpy改成strcpy_s等。如果模塊是從可信源導入的,可以選擇忽略警告。
忽略方法1:項目全局范圍:添加_CRT_SECURE_NO_WARNINGS
忽略方法 2:忽略特定模塊:如果只有其中一兩個,那么您可以在包含這些模塊時簡單地禁止警告:
#pragma warning(push)
#pragma warning(disable: 4996)
#include <sapi.h> //legacy module
#include <sphelper.h> //legacy module
#pragma warning(pop)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.