验证C++对象生命周期内地址恒定的vector示例问题排查
问题核心原因
- 你的理解完全正确:
std::vector对象本身的地址在其生命周期内恒定,resize()只会修改vector内部存储的、指向堆上元素数组的指针,不会改变vector对象自身的内存地址。 - 你代码中传入的
&vec_of_ints[0]确实是堆上元素数组的首地址,当resize()触发扩容时,元素数组会被重新分配,这个地址自然会发生变化,和你想要的vector对象本身的地址不是同一个概念。
修改方案
如果你要存储vector对象本身的地址,需要调整Class1的指针类型,修改后的可运行示例如下:
#include <iostream> #include <vector> class Class1 { public: // 指针类型改为指向vector的指针,而不是指向unsigned int的指针 Class1(std::vector<unsigned int>* vec_pt); std::vector<unsigned int>* vec_ptr; }; Class1::Class1(std::vector<unsigned int>* vec_pt) : vec_ptr(vec_pt) {} class Class2 { public: Class2(std::vector<unsigned int> vec_); std::vector<unsigned int> vec_of_ints; Class1 class1_instance; }; Class2::Class2(std::vector<unsigned int> vec_) : vec_of_ints(vec_), // 这里传入vector对象本身的地址,用&运算符直接取vec_of_ints的地址即可 class1_instance(Class1(&vec_of_ints)) {} int main() { std::vector<unsigned int> vec_test(10, 2); Class2 instance_class2(vec_test); Class1 instance_class1 = instance_class2.class1_instance; // 输出vector对象本身的地址,两个值完全相等 std::cout << "Class1中存储的vector对象地址: " << instance_class1.vec_ptr << " , Class2中vector对象的实际地址: " << &instance_class2.vec_of_ints << std::endl; // 触发扩容 instance_class2.vec_of_ints.resize(20, 3); // 扩容后vector对象地址依然不变 std::cout << "resize后Class1中存储的vector对象地址: " << instance_class1.vec_ptr << " , resize后Class2中vector对象的实际地址: " << &instance_class2.vec_of_ints << std::endl; // 验证修改可见性:修改Class2中vector的元素,从Class1的指针访问得到相同值 instance_class2.vec_of_ints[0] = 100; std::cout << "通过Class2直接访问vec[0]: " << instance_class2.vec_of_ints[0] << " , 通过Class1指针访问vec[0]: " << (*instance_class1.vec_ptr)[0] << std::endl; return 0; }
运行结果说明
修改后的代码运行后你会看到:
- 无论是否执行resize,Class1存储的vector对象地址和Class2中vector的实际地址完全一致,验证了成员变量地址在生命周期内恒定的结论。
- 对Class2中vector的任何修改(包括元素值修改、扩容),都可以通过Class1存储的vector指针正常访问到最新结果,满足你的需求。
内容的提问来源于stack exchange,提问作者SolidMechanicsFan
相关产品推荐
相关产品推荐

