我是初学者,我正在学习如何在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位终极版。 谢谢你的时间!
答案 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不会对目标缓冲区进行任何长度检查,这可能会导致堆栈溢出,从而允许攻击者在被利用时执行恶意代码或只是破解应用程序