列表初始化的char数组是否仍为空终止?

Cha*_*had 6 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
Run Code Online (Sandbox Code Playgroud)

在ca上调用库strlen函数(不是以null结尾)会导致未定义的行为.Lippman等人说"这次调用的最可能的影响是,strlen将继续查看跟随ca的内存,直到遇到空字符."

稍后的练习将询问以下代码的作用:

const char ca[] = {'h','e','l','l','o'};
const char *cp = ca;
while (*cp) {
   cout << *cp << endl;
   ++cp;
}
Run Code Online (Sandbox Code Playgroud)

我的分析:ca是一个非空终止的char数组.cp,一个指向char的指针,最初保存ca [0]的地址.while循环解除引用指针cp的条件,将生成的char值上下文转换为bool,并仅在转换结果为"true"时执行循环块.由于任何非null char都转换为bool值'true',循环块执行,将指针递增char的大小.然后循环遍历内存,打印每个char,直到到达空字符.因为ca不是以空值终止的,所以循环可以继续远远超过ca [4]的地址,将后来的内存地址的内容解释为字符并将它们的值写入cout,直到碰巧遇到发生的一大块位表示空字符(全0).这种行为类似于Lippman等人在前面的例子中提出的strlen(ca).

但是,当我实际执行代码(再次使用g ++ -std = c ++ 11进行编译)时,程序会一直打印:

'h'
'e'
'l'
'l'
'o'
Run Code Online (Sandbox Code Playgroud)

并终止.为什么?

Mik*_*eMB 4

最可能的解释是:在现代桌面/服务器操作系统(如 Windows 和 Linux)上,内存在映射到程序的地址空间之前会被清零。因此,只要程序不将相邻的内存位置用于其他用途,它就会看起来像一个以 null 结尾的字符串。在您的情况下,相邻字节可能只是填充,因为大多数变量至少是 4 字节对齐的。

就语言而言,这只是未定义行为的一种可能实现。