Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 动态阵列内存分配是如何工作的?_C++_Arrays_Memory - Fatal编程技术网

C++ 动态阵列内存分配是如何工作的?

C++ 动态阵列内存分配是如何工作的?,c++,arrays,memory,C++,Arrays,Memory,编辑:因为我在没有源代码的情况下发布了一个关于TArray的错误问题,所以我用std::vector替换了它 我在main函数中定义了一个动态数组 std::vector<sSymbols> arrSymbols; 为什么在某些时候地址会发生变化 我需要创建指向这些元素的指针数组,并在每次符号增加时添加新元素(指针) 但是经过几次迭代之后,数组中的指针指向了错误的数据。正如我在对问题的评论中所说的,您不能依赖于类的存储始终位于同一个位置。它很可能会随着您向其中添加元素而增长—为此

编辑:因为我在没有源代码的情况下发布了一个关于TArray的错误问题,所以我用std::vector替换了它

我在main函数中定义了一个动态数组

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