系统相关
首页 > 系统相关> > c – 为什么对new []的连续调用不会分配连续的内存?

c – 为什么对new []的连续调用不会分配连续的内存?

作者:互联网

我正在使用64位的Ubuntu 14.04.这是我的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!操作系统在0x1195020 – 0x119502F,0x1195038 – 0x0x119504F用于什么?

解决方法:

因为:

>每个分配内存块的开头和结尾的一些空间通常用于簿记. (特别是,许多分配器发现在那里存储前/后块的大小或指向它们的指针是有用的.)
>内存分配器可以“舍入”分配块的大小,以使其更容易.例如,如果不是16或32,则7字节的分配可能会被舍入到8字节.
>内存块可能已在非连续位置可用. (请记住,在main()运行之前,C运行库可能已经自己进行了一些内存分配.)
>分配器可能有一个计划用于布局内存,这会通过将下一个块放在“下一个”地址来破坏. (例如,它可能会为特定大小的分配保留该内存.)
>为什么要这样?没有保证.分配的内存可能会在任何地方结束. (好吧,差不多.)不要做任何假设,只要让记忆去分配器说它会去的地方,你会没事的.

标签:c,linux,memory,heap-memory
来源: https://codeday.me/bug/20191008/1871512.html