c++ - 列表初始化的 char 数组是否仍然以 null 结尾?

标签 c++ pointers char

当我阅读 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/

相关文章:

c++ - 我究竟该如何使用 Boost?

c - Typedefed 数组类型不可分配

C 指针解引用错误

java - 棘手的 Java 字符串面试问题。给定 List<String> 和 char [] 返回仅包含 char [] 的最长字符串

c++ - 如何正确声明我的 if 或 while 语句以满足所需的输入?

c++ - 当返回指向本地数组的指针时,为什么它总是相同的值?

c++ - if (cin >> x) 和 if (!(cin >> x).fail()) 有什么区别?

c - 分配超大内存 - C 中的指针

java - 使用.toUpperCase()编译代码时得到 'char cannot be dereferenced error';

c++ - 初始化字符串 vector 数组时出错