C-分配大量char*时,为什么内存大小会加倍

  • 本文关键字:内存 分配 char c linux malloc
  • 更新时间 :
  • 英文 :


i分配一个2D的char *阵列,每个字符串长度为12。
50行和2000000列。

让我们计算: 50*2000000 * (12(length)+8(for pointer))。我使用64位。

50 * 2000000 * 20 = 2000000000位..-> 2 GB。

当我检查内存监视器时,它表明该过程需要4 GB。
(分配后发生的所有事情)

这是代码:

int col=2000000,row=50,i=0,j=0;
char *** arr;
arr=(char***)malloc(sizeof(char**)*row);
for(i=0;i<row;i++)
{
arr[i]=(char ** )malloc(sizeof(char*)*col);
    for(j=0;j<col;j++)
     {
         arr[i][j]=(char*)malloc(12);
         strcpy(arr[i][j],"12345678901");
         arr[i][j][11]='';
     }
}

可能来自Linux中的页面?

malloc的每个呼叫的记忆都比您提出的更多。Malloc需要存储有关分配位置的内部信息,例如分配的空间的大小,有关邻居块的一些信息等。(很可能)每个返回的指针都与16个字节对齐。在我的估计中,每个分配的12个字节都需要32个字节。如果您想保存内存,将所有字符串分配为一个malloc,然后将它们分为每12个尺寸。尝试以下内容:

int col=2000000,row=50,i=0,j=0;
char *** arr;
arr= malloc(sizeof(*arr)*row);
for(i=0;i<row;i++)
{ 
  arr[i]= malloc(sizeof(*arr[i])*col);
  char *colmem = malloc(12 * col);
  for(j=0;j<col;j++)
  {
     arr[i][j] = colmem + j*12;
     strcpy(arr[i][j],"12345678901");
  }
}

我会从头开始重写代码。由于某种原因,所有C程序员中约有99%不知道如何动态分配正确的2D数组。我什至不确定我是1%的人之一,但让我们试一试:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main()
{
  const int COL_N = 2000000;
  const int ROW_N = 50;
  char (*arr)[ROW_N] = malloc( sizeof(char[COL_N][ROW_N]) );
  if(arr == NULL)
  {
    printf("Out of memory");
    return 0;
  }
  for(int row=0; row<ROW_N; row++)
  {
    strcpy(arr[row], "12345678901");
    puts(arr[row]);
  }
  free(arr);
  return 0;
}

这里的重要部分是:

  • 您应该始终在相邻内存单元格中分配多维数组或它们不是数组,而是基于指针的查找表。因此,您只需要一个单个Malloc呼叫。
  • 这应该节省一些内存,因为您只需要一个指针,并且将其分配在堆栈上。没有指针在堆上分配。
  • 施放malloc的回报值毫无意义(但对现代编译器来说并不危险)。
  • 确保Malloc实际上有效,尤其是在分配可笑的记忆时。
  • strcpy复制了零终止,您无需手动进行。
  • 无需嵌套环。您想分配一个2D数组,而不是3D。
  • 即使操作系统可能会为您服务,始终清理自己的烂摊子()。

相关内容

  • 没有找到相关文章

最新更新