c++ 为什么cout &char操作相同的表达式不能返回相同的答案

mrphzbgm  于 2023-06-25  发布在  其他
关注(0)|答案(2)|浏览(110)
#include "iostream"

using namespace std;

int main() {
    char c = 'x';
    cout << &c << endl;
}

cout << &c << endl打印'x'
2.

#include "iostream"

using namespace std;

int main() {
    int x = 222222;
    char c = 'x';
    cout << &c << endl;
    cout << x << endl;
}

cout << &c << endl; print 'xd',似乎是变量的地址
操作系统版本
Linux vm 5.19.0-45-generic #46-Ubuntu SMP PREEMPT_DYNAMIC Wed Jun 7 09:08:58 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
GCC版本
gcc版本12.2.0(Ubuntu 12.2.0- 3ubuntu 1)
表达方式都是一样的,为什么会不一样呢?

l7mqbcuq

l7mqbcuq1#

你正在阅读c的边界,因此你的程序的行为是未定义的。
char*传递给std::cout<<操作符时,它将该指针视为c风格的以null结尾的字符串。这意味着它将从指针所指向的字节开始连续阅读字符,直到找到nul(0)字节。
但是一个char不是nul终止的,所以cout会尝试从char对象后面读取数据,导致未定义的行为。在实践中,它最终会漫游到表示int222222的字节中,并将它们解释为字符。最后它会找到一个nul字节并停止(希望在它走出进程当前Map的地址空间并崩溃之前)。

i7uaboj4

i7uaboj42#

问题是

char c = 'x';
cout << &c << endl;

因为&c是一个char*,它将使用这个operator<<

template< class Traits >
basic_ostream<char, Traits>&
    operator<<( basic_ostream<char, Traits>& os, const char* s );

该函数将使用std::char_traits<char>::length(reinterpret_cast<const char*>(s))来计算要插入到流中的字符数。这个功能反过来

  • 返回s指向的字符序列长度,即结束空字符的位置。

因为你只有一个char(不是\0),length函数将读取内存中x之后的任何内容。这具有未定义的行为,因此它可能会崩溃或在某处找到\0并将大量垃圾插入流中。
如果你想打印它的地址,转换为void*

std::cout << static_cast<void*>(&c) << '\n';

相关问题