为什么C中的strcpy不安全?

时间:2014-04-26 23:31:22

标签: c string strcpy

我是初学者,我正在学习如何在C语言中复制字符串。

这是我刚遇到的一个问题:

每次我尝试使用“strcpy”命令从字符串1复制到字符串2时,Visual Studio 2013会给我一条错误/警告消息,说“strcpy”不安全,建议我改用strcpy_s。

您能否解释为什么使用strcpy不安全?什么是strcpy的更安全的替代品?

这是我的代码:

#include<stdio.h>
#include<string.h>
main()
{
    char str1[] = "Copy a string.";
    char str2[15];
    char str3[15];
    int i;

    /* with strcpy() */
    strcpy(str2, str1);
    /* Without strcpy() */
    for (i = 0; str1[i]; i++)
        str3[i] = str1[i];
    str3[i] = '\0';
    /* Display str2 and str3 */
    printf("The content of str2: %s\n", str2);
    printf("The content of str3: %s\n", str3);
    return 0;
}

P.S。我在Windows 7 64位终极版上使用Visual Studio 2013 64位终极版。 谢谢你的时间!

3 个答案:

答案 0 :(得分:8)

strcpy无法知道目标缓冲区有多大(即没有长度参数),因此使用它的草率编程可能导致超出缓冲区并破坏其他内存。这种超支可能导致崩溃,奇怪的行为,并可能被恶意软件作者利用。

顺便说一下,看一下带有长度参数的strncpy。需要注意的一个问题是,如果缓冲区太小,strncpy将不会终止字符串,因此以自己的方式存在危险。

在回答您的评论/问题时 - 它将取决于具体情况。如果您知道缓冲区足够大(例如,您在前一行中以正确的大小分配它),请使用strcpy。如果有任何溢出的可能性,那么使用strncpy并确保将缓冲区中的最后位置设置为null。请注意&#34;任何可能性&#34;应该非常慷慨地解释 - 除非之前的五行或六行足以显示安全性,然后使用strncpy。

另见Andon关于strncpy_s的评论。最后,如果您使用strcpy,则可能需要添加#pragma以禁止该位置的警告。

答案 1 :(得分:2)

这是您的原始代码:

int main() {
    char str1[] = "Copy a string.";
    char str2[15];

    strcpy(str2, str1);
}

现在,三天后,您将编辑此代码。您已经意识到您确实需要编写消息"This code is copying a string."而不是。

int main() {
    char str1[] = "This code is copying a string.";
    char str2[15];

    strcpy(str2, str1);
}

但是,您现在不小心引入了缓冲区溢出。

strcpy_s需要str2长度的额外参数。这样,虽然您可能无法将整个字符串放入新缓冲区,但您不会导致未定义的行为。

答案 2 :(得分:0)

与strncpy和strcpy_s不同,strcpy不会对目标缓冲区进行任何长度检查,这可能会导致堆栈溢出,从而允许攻击者在被利用时执行恶意代码或只是破解​​应用程序