为什么这在 c++ 字符数组中有效

Why does that works in c++ char arrays

本文关键字:数组 有效 字符 c++ 为什么      更新时间:2023-10-16

我有下一个代码:

    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

那么,为什么会这样呢?为什么它不以某种方式受到限制?无论我放什么而不是"你好醇厚",它都可以工作并打印出来。

之所以有效,是因为strcpy不会检查目标数组是否至少与源数组一样大。当您使用无效参数调用strcpy时,您的代码会调用未定义的行为,并且由于该行为未定义,因此任何事情都可能发生;在您的情况下,内存将被静默覆盖。您的程序也可能崩溃。

一般来说,C 和 C++ 不检查边界(不像其他高级语言:Java、PHP、Python、Javascript 等(。

这意味着,如果您尝试strcopy (例如(一个 13 字节的字符串(例如 "Hello mellow" 到字符数组(,它不会检查给定数组是否已使用足够的内存来实例化该字符串。它只会将给定的字符串逐个字符复制到给定的内存指针。

这里发生的事情是,你在内存中的一些地方写你不应该访问;偶尔,这个程序可能会崩溃,除了:分段错误之外没有其他迹象。

如果你碰巧尝试这个...

char arr1[8];
char arr2[8];
strcpy(arr1,"Hello mellow");
printf("%sn", arr1);
printf("%sn", arr2);

。很有可能(但不是 100% 确定,请参阅评论(您会得到以下输出:

Hello mellow
llow

为什么?因为第二个char[]会被您尝试放入第一个中的数据覆盖,而没有足够的保留空间。

请参阅:http://en.wikipedia.org/wiki/Stack_buffer_overflow

C/C++ 中的本机数组是非常低级的抽象,在许多用例中被视为指向内存位置的指针。所以,当arr传递给strcpy时,strcpy只知道arr[0]的地址。因此,不可能进行边界检查。出于性能原因,这是一件非常好的事情。程序员有责任确保他/她安全地使用这些低级构造,例如,通过使用strncpy并给出适当的边界,或者使用 std::vector 并显式检查边界,或者在访问位置时使用std::vector::at来检查边界。

我认为

这是因为没有检查运行时和编译时间,如果你幸运的话,你不会得到分段错误;