C++ 为什么这些变量的地址打印为ab@和b@?
我运行以下代码:C++ 为什么这些变量的地址打印为ab@和b@?,c++,memory-address,C++,Memory Address,我运行以下代码: #include <iostream> using namespace std; typedef struct Test { char a; char b; int i; double d; }Test; int main() { Test test; test.a = 'a';
#include <iostream>
using namespace std;
typedef struct Test
{
char a;
char b;
int i;
double d;
}Test;
int main()
{
Test test;
test.a = 'a';
test.b = 'b';
test.i = 478;
test.d = 4.7;
cout << &test.a << '\n'
<< &test.b << '\n'
<< &test.i << '\n'
<< &test.d << '\n';
return 0;
}
起初,我认为这是&
和
之间优先级的结果但是
0x28fe94
和0x28fe94
表明这不是优先级问题。我能弄清楚
ab@
和b@
是什么意思?它意味着未定义的行为。const char*
有一个特殊的重载,它将其打印为以null结尾的字符串。你的没有终结者,所以它超越并触发前面提到的UB。用石膏固定:
std::cout << static_cast<void *>(&test.a) << '\n'
<< static_cast<void *>(&test.b) << '\n'
<< &test.i << '\n'
<< &test.d << '\n';
std::cout当你写
cout << &test.a
希望这有帮助 因为在使用&test.a
和&test.b
时传递的是字符的地址,cout
运算符将地址视为字符串的开头。这就是为什么您首先获得ab@
,然后获得b@
。@
不太明显;它位于结构中两个char
值之后和int
值之前的填充中,是准随机垃圾。实际上,您正在调用未定义的行为,因为您要求输出代码访问填充。如果要打印地址,请强制转换为void*
。如果要打印字符,请不要提供地址。如果字段是给定的数值,这真的是未定义的行为,还是未指定的行为?@templatetypedef,我在Coliru上得到了不同的输出,所以有一个开始。其他成员可能会发生一些事情,但据我所知,只要它们按顺序出现(似乎不包括这种行为),它们就可以重新排列,因此从技术上讲,它可以是最后一个,从最大到最小,并且可以有填充,我不确定这是否需要0字节。不妨提及非ASCII的可能性,但你已经知道了。不过,我完全同意您对实际发生的情况的解释。@templatetypedef:无法保证结构打包(事实上,考虑到使用的数据类型,这不太可能),因此在假定的ASCIIZ字符串流传输期间首次读取的字段之间可能存在未初始化的内存。。。不是所有未初始化的读取都有未定义的行为吗?我得再检查一下标准。只有当CPU支持写入机器字中的特定字节,并且编译器使用这些指令时,才可能产生影响,但这不是一个荒谬的假设。
cout << &test.a
cout << static_cast<void*>(&test.a)