c++ - 为什么连续调用 new[] 不分配连续内存?

标签 c++ linux memory heap-memory

我使用的是 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 有什么用?

最佳答案

因为:

  1. 每个已分配内存块的开头和结尾的一些空间通常用于簿记。 (特别是,许多分配器发现在周围存储前面/后面的 block 的大小或指向它们的指针很有用。)

  2. 内存分配器可能会“四舍五入”已分配 block 的大小以使其更容易。例如,7 字节的分配可能会四舍五入到 8 字节,如果不是 16 或 32。

  3. 内存块可能已经在不连续的位置可用。 (请记住,甚至在 main() 运行之前,C 运行时可能已经在自己进行一些内存分配。)

  4. 分配器可能有一个内存布局计划,如果将下一个 block 放在“下一个”地址,内存就会被破坏。 (例如,它可能已为特定大小的分配保留该内存。)

  5. 为什么要这样做?没有任何保证。分配的内存可能会在任何地方结束。 (好吧,差不多。)不要做任何假设,只要让内存去分配器指定的任何地方,你就会没事的。

关于c++ - 为什么连续调用 new[] 不分配连续内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25677458/

相关文章:

c++ - cout 两次返回一串字符

python - 以编程方式设置文件写入速率

node.js - 从 Docker 容器 Web 应用程序内部触发主机操作系统上的事件

java将zip文件打开到内存中

C++ 比较两个整数值,一个简单值和一个指针

c++ - 如何在 OpenCV 中找到两个灰度图像的重叠部分?

c++ - .get() 和 -> 与智能指针之间有区别吗?

Python3 pip3 无法安装requests

c - 是否可以在共享内存上加载共享库?

Java线程内存计算