两个对象似乎共享相同的地址
Two objects seem to share the same address
我正在使用Visual Studio Ultimate 2013 Preview,Windows 7。
我正在使用 CRTP 能够方便地将任何类型的对象推送到单独的向量中。
然而,结果很奇怪。你会看到我有两个类,A
和 B
派生自Container
。使用T* PushOne()
将新实例推送到静态向量中,并返回其地址以供使用。
但是,出于某种原因,类 A
的第一个实例化对象和类B
的第一个实例化对象似乎共享相同的地址。
代码如下:
template <typename T>
class Container{
public:
static std::vector<T> elements;
static T* PushOne(){
//Push a new T object into the vector
elements.push_back( T{} );
//Print out its address
std::cout << "Make " << typeid(T).name() << " at " << &elements[elements.size() - 1] << "n";
//Return its address.
return &elements[elements.size() - 1];
}
};
template <typename T>
std::vector<T> Container<T>::elements;
class A : public Container<A>{
};
class B : public Container<B>{
};
int main(int argc, char** args){
std::cout << "First addresses:n";
//a and c are assigned the address
auto a = Container<A>::PushOne();
auto b = Container<A>::PushOne(); //Problem gone if this is commented
auto c = Container<B>::PushOne();
std::cout << "nLater addresses:n";
std::cout << &Container<A>::elements[0] << "n"
<< &Container<A>::elements[1] << "n"
<< &Container<B>::elements[0] << "n";
std::cin.get();
}
在我的机器上运行一次的输出:
First addresses:
Make class A at 00700350
Make class A at 006FA929
Make class B at 00700350
Later addresses:
006FA928
006FA929
00700350
如您所见,第一个和最后一个条目(分别存储在变量 a
和 b
中)首先打印相同的地址。
当我第二次打印地址时,我得到的第一个 A* 的不同结果。
除非我注释掉auto b = ...
行,否则我总是得到相同的结果。如果我这样做,a
和b
会被分配不同的地址。
第二个 push_back/PushOne 会导致std::vector<A>
重新分配以增加它,因此现在第一个 A 元素不再位于 00700350
。
您的Later addresses
打印输出证实了这一点。
当你将元素推到向量上时,最终它将需要分配新的内存,并释放旧的内存(其他分配可能会使用)。 所以,显然,当你第二次推迟Container<A>
时,发生了重新分配。 然后,当你推送Container<B>
时,它的向量使用了另一个向量(Container<A>
)释放的内存。 这完全没问题。
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- 空基优化子对象的地址
- 禁用地址共享注册表不起作用
- 不同类的虚拟函数共享相同的(无效?)内存地址
- ptrA = ptrB 是否等同于 ptrA = &*ptrB?,空值是否共享一个地址空间?
- 我可以检查共享内存中是否存在地址
- 查询与将地址分配给共享_ptr有关
- 引用如何共享内存地址
- 共享库中的成员函数指针地址
- CUDA:结构体的共享数据成员和对该结构体的引用成员具有不同的地址和值
- 两个对象似乎共享相同的地址
- 为什么 a 和 b 在下面的代码中共享相同的地址
- 尝试使用pthreads访问共享数据数组时,出现“无法访问内存地址”错误
- 如何判断共享库在进程地址空间中的加载位置
- 将memmove函数与临时指针共享相同的地址
- CUDA 运行时错误:未指定的启动失败 & 超出范围的共享或本地地址
- 如何为共享内存映射选择固定地址
- 其他对象中的对象是否真的共享相同的地址
- 为什么字符串形参与实参共享相同的地址