C++中仅定义一个void* p为何输出&p与p得到两个不同地址
C++ 指针变量输出双地址的原理解释
对应问题涉及的代码:
void *p ; cout<<&p<<p;
两个输出值的本质拆解
- 输出项
&p:获取的是指针变量p自身在内存中的存储地址。只要是通过变量名声明的实体,编译器就会为它分配独立的内存空间,哪怕它是指针类型。void *p本质上是一个需要占据自身内存的变量,在64位系统中通常会占用8字节的栈内存,&p就是这块专门用来存指针本身的内存的起始地址。 - 输出项
p:获取的是指针变量p自身内存空间里存储的内容值。指针类型变量的特殊点就在于,它内存里存的内容,就是一个指向其他内存位置的地址值。因为代码里的p是未初始化的野指针,对应的栈内存不会被编译器自动清零,里面存的是之前栈空间遗留的随机垃圾值,并不是开发者主动定义的有效地址,这也是两个输出值看起来差异特别大的直接原因。
为什么两个地址必然不同
核心是很多新手会把“指针变量本身”和“指针存储的指向地址”混为一谈,这俩是完全独立的两层内存关系:
- 可以用非常直白的对应关系理解:你在便签上写下一个朋友的联系方式。那
&p就是这张便签本身放在你书桌哪个位置,p就是便签上写的那个朋友的联系方式。这俩从定义上就属于完全不同的东西,根本不存在“只声明一个变量为什么出现两个地址”的矛盾。 - 哪怕给p显式赋值一个有效地址,两个值也依然会是完全独立的两个地址。比如写如下初始化代码:
int temp = 10; void *p = &temp; cout << &p << " " << p;
此时输出的两个值,前者是p这个指针自身的栈地址,后者是temp这个int变量的栈地址,二者会存在固定的栈内存偏移量,永远不会重叠——除非故意写出p自己指向自己的特殊错误逻辑,那属于内存违规操作,不是正常代码的运行结果。
补充说明:指针只是一种特殊类型的变量,它和int、char等普通变量没有本质区别,唯一的差异是它存储的内容被编译器解释为内存地址,而不是整数或字符。只要是变量,就必然有自己的内存地址,这就是两个输出值来源完全独立的根本原因。
内容的提问来源于stack exchange,提问作者HT 3163
相关产品推荐
相关产品推荐

