如何修复编译错误“此函数或变量可能不安全”(strcpy)

Ric*_*rdo 1 c++ string pointers char

我看到了我不久前完成的一个古老的简单算法。我是用 dev-c++ 做的,但现在我在 Visual Studio 中编译了它,但它不起作用。Visual Studio 编译器说:'strcpy':此函数或变量可能不安全。考虑使用 strcpy_s 代替。要禁用弃用,请使用 _CRT_SECURE_NO_WARNINGS。(第 17 行)

在这个简单的项目中,您将输入一个短语,然后将短语翻译成十六进制(每个字符)。

那么为什么 dev-c++ 没有告诉我呢?我犯了什么错误吗?还是不行...代码没问题?我想了解这一点,因为这不是我第一次收到该错误。

代码执行示例:

请插入一句话:你好世界!字符串 -hello world!- 以十六进制转换为 68 65 6c 6c 6f 20 77 6f 72 6c 64 21

#include <iostream>
#include <iomanip>
#include <string>
#include <cstring>

using namespace std;

int main()
{
    string phrase;
    char* chArray;

    cout << "Pls insert a phrase:\t";
    getline(cin, phrase);

    chArray = new char[phrase.size() + 1];
    strcpy(chArray, phrase.c_str());         //THE ERROR IS HERE!

    cout << "The string -" << phrase << "- converted in hex is\n";
    for (int i = 1; i < static_cast<int>(phrase.size() + 1); i++)
    {
        int ch = (int)chArray[i-1];
        cout << setbase(16) << ch << " ";
        if (i % 5 == 0)
            cout << "\n";
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

And*_*dyG 6

当您使用任何“不安全”字节复制函数时,您会收到此警告。它主要针对 MSVC。

要修复它,请使用strcpy_swhich 还要求您传递要复制的最大字节数(这应该是目标缓冲区的大小)。这可以防止缓冲区溢出。

strcpy_s(chArray, phrase.size()+1, phrase.c_str());
Run Code Online (Sandbox Code Playgroud)

也就是说,std::string在 C++ 中更容易使用所有这些


eer*_*ika 6

Visual Studio 编译器显示:“strcpy”:此函数或变量可能不安全。

这是因为你使用过strcpy,并且您的编译器认为它是一个潜在不安全的函数。该警告的目的是告知您这种缺乏安全感的情况。如果您希望继续使用该功能,该消息会建议您如何禁用该警告。

典型的、更安全的替代方案是使用std::string。对于您的特定程序,使用strcpy似乎完全多余。相反chArray[i-1],您可以使用phrase[i-1].

那么为什么 dev-c++ 不告诉我呢?

诊断消息由实现自行决定。您在此 IDE 中使用了另一个编译器,并且该编译器不会警告您使用strcpy.

我犯了什么错误吗?

有人可能会认为选择使用strcpy是一个错误。但这是一个错误,因为它很容易被意外误用。据我所知,您使用它是正确的。

也就是说,不安全的部分原因是不正确的使用不一定容易识别。如果它很简单,那么编译器会在您错误使用它时告诉您。但这并不容易,编译器通常无法做到这一点。


除了使用 之外strcpy,还有另一个潜在问题:您泄漏了为字符数组分配的内存。