列表初始化的 char 数组是否仍以 null 结尾? [英] Are list-initialized char arrays still null-terminated?

查看:21
本文介绍了列表初始化的 char 数组是否仍以 null 结尾?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读 Lippman C++ Primer(第 5 版,C++11)时,我发现了以下代码:

As I worked through the Lippman C++ Primer (5th ed, C++11), I came across this code:

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

在非空终止的 ca 上调用库 strlen 函数会导致未定义的行为.Lippman 等人说,这个调用最可能的效果是 strlen 将继续查看 ca 后面的内存,直到遇到空字符."

Calling the library strlen function on ca, which is not null-terminated, results in undefined behavior. Lippman et al say that "the most likely effect of this call is that strlen will keep looking through the memory that follows ca until it encounters a null character."

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

A later exercise asks what the following code does:

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

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

My analysis: ca is a char array that is not null-terminated. cp, a pointer to char, initially holds the address of ca[0]. The condition of the while loop dereferences pointer cp, contextually converts the resulting char value to bool, and executes the loop block only if the conversion results in 'true.' Since any non-null char converts to a bool value of 'true,' the loop block executes, incrementing the pointer by the size of a char. The loop then steps through memory, printing each char until a null character is reached. Since ca is not null-terminated, the loop may continue well past the address of ca[4], interpreting the contents of later memory addresses as chars and writing their values to cout, until it happens to come across a chunk of bits that happen to represent the null character (all 0's). This behavior would be similar to what Lippman et al suggested that strlen(ca) does in the earlier example.

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

However, when I actually execute the code (again compiling with g++ -std=c++11), the program consistently prints:

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

并终止.为什么?

推荐答案

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

Most likely explanation: On modern desktop/server operating systems like windows and linux, memory is zeroed out before it is mapped into the address space of a program. So as long as the program doesn't use the adjacent memory locations for something else, it will look like a null terminated string. In your case, the adjacent bytes are probably just padding, as most variables are at least 4-Byte aligned.

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

As far as the language is concerned this is just one possible realization of undefined behavior.

这篇关于列表初始化的 char 数组是否仍以 null 结尾?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆