为什么这在 c++ 字符数组中有效
Why does that works in c++ char arrays
我有下一个代码:
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
来检查边界。
这是因为没有检查运行时和编译时间,如果你幸运的话,你不会得到分段错误;
- 使用无符号字符数组有效存储内存
- 有效地计算多维数组的累积和?
- 计算数组重复次数的组合的有效算法,加起来达到给定的总和
- C++ 返回指向函数内定义的静态数组的指针是否有效?
- 声明后,gcc 的动态大小数组是否与标准数组有效相同?
- 如何有效地找到数组中三元组和的最小差异?
- 如何在C++中有效地将数字值重新分配给字符数组
- 如何有效地收集给定数组中的重复元素?
- 创建字符串数组的有效方法
- 如何在C++中有效地将数组移动到向量
- 在递归函数中更有效地创建对象和对象数组?C++
- 张量(多维数组)是树前瞻数据的有效存储类型吗?
- 有效地展平结构数组
- cpp 数组 - 分配常量索引有效,而非常量索引不起作用
- 如何在整数数组中有效地存储大量数字?C++
- 有效地从文本文件中读取带有字符串索引的大型二维数组(矩阵)
- 如何有效地使用 std::async 对指针数组执行操作
- 数组有效,而矢量无效。我做错了什么?
- 为什么包含字符串文字的初始化器对初始化“char”数组有效
- 是return*数组;有效的