我的对象在矢量中的地址改变了
The address of my object in a vector changes
我用A
对象填充了一个向量,然后将这些对象的地址存储在一个multimap
中[1],但是打印消息显示存储在向量中的对象的引用发生了变化[2]。你知道为什么吗?以及如何避免任何更改。
//[1]
vector<A> vec;
multimap<const A*, const double > mymultimap;
for (const auto &a : A) {
double val = a.value();
vec.push_back(a);
mymultimap.insert(std::pair<const A*, const double >( &vel.back(), val));
// displaying addresses while storing them
cout<<"test1: "<<&vec.back()<<endl;
}
//[2]
// displaying addresses after storing them
for(auto &i : vec)
cout << "test2: " << &i <<endl;
结果:
test1: 0x7f6a13ab4000
test1: 0x7f6a140137c8
test2 :0x7f6a14013000
test2 :0x7f6a140137c8
您在for
循环中调用vec.push_back(a)
。因此,如果vector耗尽了空间,它可能会重新分配底层数组。因此,如果先前的元素被复制到新的内存位置,它们的地址将不再有效。
在调用vector<T>::push_back()
时不能保证保留迭代器(以及引用和对象地址)。如果新的size()
大于当前的capacity()
,将发生重新分配,所有元素被移动或复制到新的位置。
为了避免这种情况,可以在开始插入之前调用reserve()
。
std::vector
的主要特性之一是它将元素存储在连续内存中(当您在现代cpu上访问vector的项时,这对性能非常有利)。
的缺点是,当预分配的内存为向量是满的,你想要添加一个新的项目(例如调用vector::push_back()
),向量必须分配另一块连续内存,并复制/移动数据从以前的位置到新的。由于这种重新分配和复制/移动的结果,旧项的地址可能会改变。
如果出于某种原因想要保留对象的地址,而不是将这些对象的实例存储在std::vector
中,您可以考虑使用指向对象的指针向量。在这种情况下,即使在重新分配之后,对象指针也不会改变。
例如,您可以将shared_ptr
用于vector
的项和multimap
的键:
vector<shared_ptr<const A>> vec;
multimap<shared_ptr<const A>, const double> mymultimap;
相关文章:
- 将数组的地址分配给变量并删除
- 空基优化子对象的地址
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 变量没有改变?通过向量的函数调用
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 如何在c++程序中找到函数的地址
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 被解释为低级别const的const对象的地址
- 是否有保证堆分配的块地址不会改变(隐式)
- c++指针:在不改变地址的情况下改变内容
- 指针地址改变-函数
- 我的对象在矢量中的地址改变了
- 为什么每次运行时函数的地址都会改变?
- Reference_wrapper不会相应地改变地址
- 在另一个函数内部改变指针数组所包含的地址
- 链接列表中的指针地址不会改变
- 为什么这个地址在gdb中改变
- 根据信号和返回地址改变程序执行流程
- 动态数组改变内存地址位置
- 使用引用改变变量的地址