You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++内存地址异常疑问:vector引用传递与地址差异解析

解答你的C++ vector与引用地址困惑

让我一步步帮你拆解这两个问题,结合你给出的代码和输出分析:

问题1:为什么main中persons的地址(标记1)与&persons(标记2)不同?persons是指针吗?

首先要明确一个关键错误:你直接使用printf("%p", persons)的写法是未定义行为。%p格式符要求传入的参数必须是void*类型的指针,但vector<A>是一个类对象,并非指针,C++标准也没有为vector定义隐式转换到void*的规则。

你看到的标记1的地址,其实是编译器对这个错误调用的“意外输出”——大概率是取了vector对象内部某个成员变量的内存地址(比如vector内部维护的指向数据缓冲区的指针所在的位置),而不是vector对象本身的地址。

而&persons(标记2)才是vector对象真正的内存地址:persons是main函数中的局部变量,存储在栈上,&persons就是这个对象在栈上的位置。

这里要纠正一个误解:vector本身不是指针,它是一个封装了动态数组的类对象。它内部确实持有指向堆上数据缓冲区的指针,但vector对象自己是存储在栈上的(作为局部变量时),和普通的类对象没有区别。

问题2:为什么按引用传递的p(标记3)与persons(标记1)地址不同?引用传递不该地址一致吗?

同样的,printf("%p", p)也是错误的用法:p是vector<A>&类型的引用,同样不能直接传给%p格式符,标记3的地址也是编译器处理错误调用的结果。

但你看标记4的&p,它和标记2的&persons完全相同(都是0x7ffc6cc981a0)——这才是引用的正确表现!引用的本质是变量的别名,它本身不占用额外的内存空间(编译器会直接将引用的访问映射到原变量),所以&p就是原变量persons的地址,二者完全一致。

你看到的标记3和标记1的地址不同,只是因为这两个错误的printf调用分别取了同一个vector对象内部的某个成员地址(可能因为编译器在不同函数中的处理细节略有差异,但本质都是错误用法导致的非预期输出)。

补充:正确的打印方式

如果你想打印vector内部数据缓冲区的地址,应该使用data()成员函数:

printf("persons data address: %p\n", persons.data());

当vector为空时,data()返回的是nullptr(或者一个不指向有效数据的指针,不同编译器可能有差异);当push_back元素后,data()就会返回堆上数据缓冲区的起始地址,和&persons[0]一致。


内容的提问来源于stack exchange,提问作者G FL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:42:15