动态数组内存分配如何工作?

时间:2016-02-25 21:58:16

标签: c++ arrays memory

编辑:由于我发布了一个不含源代码的TArray不正确的问题,我已将其替换为std :: vector。

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

std::vector<sSymbols> arrSymbols; 

我还有一个向数组添加新元素的函数;

functionOne(std::vector<TSymbols>& arrSymbolsRef)
{
    sSymbols symbolOne;
    //some symbol struct filling
    arrSymbolsRef.push_back(symbolOne);
    for (int i = 0; i < arrSymbolsRef.size(); i++) 
       printf("arrSymbolsRef[%d] ptr is %d", i, &arrSymbolsRef[i]);
}

更新结果: 在循环中运行此函数会产生以下结果:

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

为什么在某些时候地址正在转变?

我需要创建一个指向这些元素的指针数组,并在每次增加arrSymbols时添加新元素(指针)。

但是经过几次迭代后,数组中的指针指向错误的数据。

1 个答案:

答案 0 :(得分:0)

就像我在问题评论中所说的那样,你不能依赖课程&#39;存储一直在同一个地方。它很可能必须随着您向其添加元素而增长 - 为此,它将分配一个新的更大的块,并将所有当前数据复制到其中。

仅供记录,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';
    }
}

在我的系统上给出以下结果:

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

如您所见,矢量存储的起始地址会发生几次变化。现在,由于std::vector保证了其元素的连续存储,因此其所有元素的地址也会发生变化。

我不认为有任何动态可调整大小的容器可以保证其元素的常量地址,除非您预先声明了可以存储的最大元素数量。在这种情况下,它可以立即分配一个巨大的块,而不是再次重新分配。如果您需要此类行为,请考虑使用std::array之类的内容,或者在std::vector周围创建一个不允许修改其大小的包装器。