为何相同的cout输出char变量地址表达式会得到不同结果?
为何相同的
cout << &c << endl表达式输出不同结果? 先看两段代码的执行现象:
代码1及输出
#include "iostream" using namespace std; int main() { char c = 'x'; cout << &c << endl; }
执行后输出字符x。
代码2及输出
#include "iostream" using namespace std; int main() { int x = 222222; char c = 'x'; cout << &c << endl; cout << x << endl; }
执行后输出类似xd的内容,看起来像是内存中的随机数据。
核心原因:cout对char*的特殊处理
C++标准库中,std::ostream(即cout)对char*类型有专门的重载逻辑:它会把char*视为C风格字符串,从指针指向的地址开始输出字符,直到遇到'\0'(空字符)才停止。
而&c的类型是char*,所以cout会按上述规则处理:
- 代码1的情况:变量
c在栈上单独分配,它后面的相邻内存恰好是'\0'(可能是栈初始化的零值,或是编译器的内存对齐填充)。cout输出'x'后就遇到终止符,停止输出,最终只显示x。 - 代码2的情况:栈上先分配了
int x,再分配char c。int x的二进制存储字节值不是'\0',所以cout输出'x'后,会继续读取c变量范围外的栈内存(也就是int x的部分字节),直到遇到某个'\0'才停止,因此输出了额外的字符。
重要提示:这是未定义行为
本质上,cout读取c变量范围之外的内存属于越界访问,这是C++中的未定义行为。不同编译器、编译选项、运行环境下,栈内存内容都可能不同,输出结果也会随机变化,极端情况下甚至可能导致程序崩溃。
如果想要输出char变量的地址,需要把指针转换成非char*类型,比如:
cout << static_cast<void*>(&c) << endl;
内容的提问来源于stack exchange,提问作者jurkDang
相关产品推荐
相关产品推荐

