我有下一个代码:
char arr[6] = "Hello";
strcpy(arr, "Hello mellow");
cout << strlen(arr) << ", " << arr << endl; // 12, Hello mellow
char arr1[] = "Hello";
strcpy(arr1, "Hello mellow");
cout << strlen(arr1) << ", " << arr1 << endl; // 12, Hello mellow
那么,为什么这样呢?为什么不以某种方式限制它?无论我放什么,而不是“Hello mellow”,它都可以打印出来。
答案 0 :(得分:4)
一般来说,C和C ++不会检查边界(与其他更高级别的语言不同:Java,PHP,Python,Javascript等)。
这意味着,如果您尝试将strcopy
,例如"Hello mellow"
等13个字节的字符串添加到字符数组中,就不会检查或者不是给定的数组已经实例化了足够的内存来包含字符串。它只是将给定的字符串逐字符复制到给定的内存指针。
这里发生的事情是,你在内存中的某些地方写下你不应该访问的内容;偶尔,这个程序可能会崩溃,没有其他指示:分段错误。
如果你碰巧试试这个......
char arr1[8];
char arr2[8];
strcpy(arr1,"Hello mellow");
printf("%s\n", arr1);
printf("%s\n", arr2);
...很可能(但不是100%肯定,请参阅评论)您将获得以下输出:
Hello mellow
llow
为什么呢?因为第二个char[]
会被您尝试放入第一个的数据覆盖,而没有足够的预留空间。
答案 1 :(得分:4)
它的工作原理是因为strcpy
没有检查目标数组是否至少与源数组一样大。当您使用无效参数调用strcpy
时,您的代码会调用未定义的行为,并且因为行为未定义,所以任何事情都可能发生;在您的情况下,内存被静默覆盖。你的程序也可能崩溃。
答案 2 :(得分:1)
C / C ++中的本机数组是非常低级的抽象,在许多用例中被视为指向内存位置的指针。因此,在将arr
传递给strcpy
时,所有strcpy
都知道arr[0]
的地址。结果,没有边界检查的可能性。出于性能原因,这是一件非常好的事情。程序员应该确保他/她安全地使用这些低级构造,例如使用strncpy
并给出适当的约束,或使用std::vector
并明确地检查边界或使用{ {1}}在访问位置时检查边界。
答案 3 :(得分:0)
我认为这是因为没有检查运行时间和编译时间,如果你很幸运,你不会得到分段错误;)