是列表至少的炭阵列仍未终止

Are list-initialized char arrays still null-terminated?

本文关键字:阵列 终止 列表      更新时间:2023-10-16

当我通过lippman C 底漆(第5版,C 11)时,我遇到了此代码:

char ca[] = {'C', '+', '+'};  //not null terminated
cout << strlen(ca) << endl;  //disaster: ca isn't null terminated

在CA上调用库的strlen函数,该功能并非无效,导致不确定的行为。Lippman等人说:"此呼叫最有可能的效果是Strlen将继续浏览随后CA的内存,直到它遇到无效的字符。"

以后的练习询问以下代码是什么:

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

我的分析:CA是一个未终止的char阵列。CP是CHAR的指针,最初保留了CA [0]的地址。While环路的条件将指针CP CP,上下文将所得的char值转换为bool,并仅在转换导致" true"时才能执行循环块。由于任何非循环char都会转换为" true"的bool值,因此循环块执行,以char的大小增加指针。然后循环逐步浏览内存,打印每个字符,直到达到无效字符。由于CA没有终止终止,因此循环可能会持续超过CA [4]的地址,将后来的内存地址的内容解释为字符,并将其价值观写入COUT,直到它碰巧遇到了发生的一小部分。代表空字符(全0)。这种行为将类似于Lippman等人建议Strlen(CA)在较早的示例中所做的。

但是,当我实际执行代码(再次使用G -STD = C 11)时,程序始终打印:

'h'
'e'
'l'
'l'
'o'

终止。为什么?

很可能说明:在Windows和Linux(例如Windows和Linux)等现代桌面/服务器操作系统上,在将其映射到程序的地址空间之前,将内存归零。因此,只要该程序不使用相邻的内存位置作为其他事物,它将看起来像一个无效的终止字符串。在您的情况下,相邻字节可能只是填充,因为大多数变量至少是4字节对齐的。

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

列表限制的字符阵列仍未终止?

没有隐含的null末端。

列表 - 定位式的char阵列包含一个零终止的字符串,如果至少一个字符用空末端初始化。

如果这些字符都不是零末端,则该数组不包含零端的字符串。

程序始终打印...并终止。为什么?

您分析了该数组将从界限访问。您的分析是正确的。您还应该知道,从界限访问数组的行为不确定。因此,对的答案为什么会像这样的行为是:因为行为不确定。

正如我已经提到的,您的分析是正确的。只有您(隐含的)假设是,当内存从界限访问时,第一个值必须是非零值。该假设是错误的,因为不能保证它。