当我阅读 Lippman C++ Primer(第 5 版,C++11)时,我遇到了这段代码:
char ca[] = {'C', '+', '+'}; //not null terminated
cout << strlen(ca) << endl; //disaster: ca isn't null terminated
在 ca 上调用库 strlen 函数,它不是以 null 终止的,会导致未定义的行为。 Lippman 等人说,“这个调用最可能的效果是 strlen 将继续查找跟在 ca 之后的内存,直到它遇到一个空字符。”
稍后的练习将询问以下代码的作用:
const char ca[] = {'h','e','l','l','o'};
const char *cp = ca;
while (*cp) {
cout << *cp << endl;
++cp;
}
我的分析:ca 是一个非空终止的字符数组。 cp 是一个指向 char 的指针,最初保存着 ca[0] 的地址。 while 循环的条件取消引用指针 cp,根据上下文将生成的 char 值转换为 bool,并且仅当转换结果为“真”时才执行循环 block 。由于任何非 null char 都会转换为 bool 值“true”,因此循环 block 将执行,将指针递增 char 的大小。然后循环遍历内存,打印每个字符,直到到达空字符。由于 ca 不是空终止的,循环可能会继续远远超过 ca[4] 的地址,将后面的内存地址的内容解释为字符并将它们的值写入 cout,直到它碰巧遇到一大块发生的位表示空字符(全 0)。此行为类似于 Lippman 等人在前面的示例中建议的 strlen(ca) 所做的。
然而,当我实际执行代码时(再次使用 g++ -std=c++11 编译),程序始终打印:
'h'
'e'
'l'
'l'
'o'
并终止。为什么?
最佳答案
最可能的解释:在像 windows 和 linux 这样的现代桌面/服务器操作系统上,内存在映射到程序的地址空间之前会被清零。因此,只要程序不将相邻的内存位置用于其他用途,它就会看起来像一个以空字符结尾的字符串。 在您的情况下,相邻字节可能只是填充,因为大多数变量至少 4 字节对齐。
就语言而言,这只是未定义行为的一种可能实现方式。
关于c++ - 列表初始化的 char 数组是否仍然以 null 结尾?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37955281/