C++ 动态阵列内存分配是如何工作的?
编辑:因为我在没有源代码的情况下发布了一个关于TArray的错误问题,所以我用std::vector替换了它 我在main函数中定义了一个动态数组C++ 动态阵列内存分配是如何工作的?,c++,arrays,memory,C++,Arrays,Memory,编辑:因为我在没有源代码的情况下发布了一个关于TArray的错误问题,所以我用std::vector替换了它 我在main函数中定义了一个动态数组 std::vector<sSymbols> arrSymbols; 为什么在某些时候地址会发生变化 我需要创建指向这些元素的指针数组,并在每次符号增加时添加新元素(指针) 但是经过几次迭代之后,数组中的指针指向了错误的数据。正如我在对问题的评论中所说的,您不能依赖于类的存储始终位于同一个位置。它很可能会随着您向其中添加元素而增长—为此
std::vector<sSymbols> arrSymbols;
为什么在某些时候地址会发生变化
我需要创建指向这些元素的指针数组,并在每次符号增加时添加新元素(指针)
但是经过几次迭代之后,数组中的指针指向了错误的数据。正如我在对问题的评论中所说的,您不能依赖于类的存储始终位于同一个位置。它很可能会随着您向其中添加元素而增长—为此,它将分配一个新的、更大的块,并将所有当前数据复制到其中 请注意,
std::vector
也不提供这种行为。这个简单的程序:
int main()
{
std::vector<int> a;
for(int i = 0 ; i < 17 ; ++i) {
a.push_back(i);
std::cout << "Iteration " << i << " : "
<< static_cast<void*>(&a[0]) << '\n';
}
}
如您所见,向量存储器的起始地址会更改几次。现在,由于std::vector
保证了其元素的连续存储,因此其所有元素的地址也会发生变化
我认为没有任何动态调整大小的容器可以保证其元素的地址不变,除非您预先声明了可以存储的元素的最大数量。在这种情况下,它可以一次分配一个巨大的块,而不再重新分配。如果您需要这种行为,请考虑使用类似于
std::array
,或者在std::vector
周围创建一个不允许修改其大小的包装器。如果看不到TArray
的来源,很难说,但该类似乎会自动将其当前持有的数据重新定位到其他位置。您的TArray
很可能必须重新定位,因为它试图使项目保持连续,而无法在其旧地址执行此操作。在这种情况下,在数组中存储指向项的指针是完全不安全的。这个问题取决于什么是TArray
。那是你自己写的课吗?如果是这样的话,显示它的源代码会有所帮助。如果它是其他人的,那么链接到文档至少您的代码有未定义的行为,因为%d
说您承诺通过魔法传递int
,而不是TSymbols*
。这是我能给出的唯一诚实的答案。我们怎么知道你的TArray
在做什么?哦,等等,我还有另一个给你:“用电”。std::list
保证指向元素的引用(扩展为指针)永远不会失效,只要元素没有被擦除。如果只在前面或后面添加和删除,则std::deque
会为您提供相同的保证。您还可以使用智能指针向量,在这种情况下,指针对象将是安全的。@BenjaminLindley:很好。我在思想上限制自己使用保证连续存储的容器。
arrSymbolsRef[0] ptr is -1242393600
arrSymbolsRef[0] ptr is -1257218304
arrSymbolsRef[1] ptr is -1257218244
New iteration
arrSymbolsRef[0] ptr is -1451463936
arrSymbolsRef[1] ptr is -1451463876
arrSymbolsRef[2] ptr is -1451463816
New iteration
arrSymbolsRef[0] ptr is -1450359040
arrSymbolsRef[1] ptr is -1450358980
arrSymbolsRef[2] ptr is -1450358920
arrSymbolsRef[3] ptr is -1450358860
New iteration
arrSymbolsRef[0] ptr is -1243432448
arrSymbolsRef[1] ptr is -1243432388
arrSymbolsRef[2] ptr is -1243432328
arrSymbolsRef[3] ptr is -1243432268
arrSymbolsRef[4] ptr is -1243432208
New iteration
arrSymbolsRef[0] ptr is -1243432448
arrSymbolsRef[1] ptr is -1243432388
arrSymbolsRef[2] ptr is -1243432328
arrSymbolsRef[3] ptr is -1243432268
arrSymbolsRef[4] ptr is -1243432208
arrSymbolsRef[5] ptr is -1243432148
New iteration
arrSymbolsRef[0] ptr is -1550211968
arrSymbolsRef[1] ptr is -1550211908
arrSymbolsRef[2] ptr is -1550211848
arrSymbolsRef[3] ptr is -1550211788
arrSymbolsRef[4] ptr is -1550211728
arrSymbolsRef[5] ptr is -1550211668
arrSymbolsRef[6] ptr is -1550211608
int main()
{
std::vector<int> a;
for(int i = 0 ; i < 17 ; ++i) {
a.push_back(i);
std::cout << "Iteration " << i << " : "
<< static_cast<void*>(&a[0]) << '\n';
}
}
Iteration 1 : 0x1aa9050
Iteration 2 : 0x1aa8c20
Iteration 3 : 0x1aa8c20
Iteration 4 : 0x1aa9070
Iteration 5 : 0x1aa9070
Iteration 6 : 0x1aa9070
Iteration 7 : 0x1aa9070
Iteration 8 : 0x1aa90a0
Iteration 9 : 0x1aa90a0
Iteration 10 : 0x1aa90a0
Iteration 11 : 0x1aa90a0
Iteration 12 : 0x1aa90a0
Iteration 13 : 0x1aa90a0
Iteration 14 : 0x1aa90a0
Iteration 15 : 0x1aa90a0
Iteration 16 : 0x1aa90f0