动态数组内存分配如何工作
How does dynamic array memory allocation work?
编辑:由于我发布了一个没有源代码的 TArray 的不当问题,我将其替换为 std::vector。
我在主函数中定义了一个动态数组
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
为什么在某些时候地址会发生变化?
我需要创建一个指向这些元素的指针数组,并在每次增加 arrSymbol 时添加新元素(指针)。
但是经过几次迭代后,数组中的指针指向了错误的数据。
就像我在问题的评论中所说的那样,你不能一直依赖类的存储都在同一个地方。当你向它添加元素时,它很可能必须增长 - 为此,它将分配一个新的、更大的块,并将所有当前数据复制到其中。
仅供记录,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
创建一个包装器。
相关文章:
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 当 int 方法工作正常时,void 方法有何不同,或者为什么我不能调用 void 方法?
- sdl软件渲染器不工作,工作在硬件加速的一个