我使用的是 Ubuntu 14.04 64 位。这是我的 C++ 代码,用于查看内存的使用情况。
int main() {
int **ptr;
ptr = new int* [2];
cout << &ptr << " -> " << ptr << endl;
for (int r = 1; r <= 2; r++) {
ptr[r-1] = new int [2 * r];
cout << &ptr[r-1] << " -> " << ptr[r-1] << endl;
for (int c = 0; c < 2 * r; c++) {
ptr[r-1][c] = r * c;
cout << &ptr[r-1][c] << " -> " << ptr[r-1][c] << endl;
}
}
return 0;
}
这是我的输出:
0x7fff09faf018 -> 0x1195010
0x1195010 -> 0x1195030
0x1195030 -> 0
0x1195034 -> 1
0x1195018 -> 0x1195050
0x1195050 -> 0
0x1195054 -> 2
0x1195058 -> 4
0x119505c -> 6
我预计操作系统会连续分配内存。所以 ptr[0][0] 会在 0x1195020 而不是 0x1195030!? OS 在 0x1195020 - 0x119502F、0x1195038 - 0x0x119504F 有什么用?
最佳答案
因为:
每个已分配内存块的开头和结尾的一些空间通常用于簿记。 (特别是,许多分配器发现在周围存储前面/后面的 block 的大小或指向它们的指针很有用。)
内存分配器可能会“四舍五入”已分配 block 的大小以使其更容易。例如,7 字节的分配可能会四舍五入到 8 字节,如果不是 16 或 32。
内存块可能已经在不连续的位置可用。 (请记住,甚至在
main()
运行之前,C 运行时可能已经在自己进行一些内存分配。)分配器可能有一个内存布局计划,如果将下一个 block 放在“下一个”地址,内存就会被破坏。 (例如,它可能已为特定大小的分配保留该内存。)
为什么要这样做?没有任何保证。分配的内存可能会在任何地方结束。 (好吧,差不多。)不要做任何假设,只要让内存去分配器指定的任何地方,你就会没事的。
关于c++ - 为什么连续调用 new[] 不分配连续内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25677458/