自由分配的数组内存(vs普通var?)

时间:2015-12-25 20:19:59

标签: c arrays pointers memory-management

我知道当我们为var分配内存时,我们需要通过使用指向var的指针调用free()func来释放空间(并且不要让指针悬空)。

但是当我们为变量数组分配内存时我们该怎么办? 我们应该去释放数组[0..n]的每个成员,还是仅仅为第一个成员释放指针?

long *array_p; 
size_t elements_num = 5

array_p = malloc(elements_num*sizeof(long));

选项#1:

free(array_p);
array_p=NULL;

选项#2:

for (i=0; i<array_len-1; ++i)
{
    free(array_p+i);
    array_p+i= NULL;
}

5 个答案:

答案 0 :(得分:2)

问题不在于您是否正在分配数组,而是在分配指针数组。

您使用的每个free / malloc都需要calloc。现在处于类似

的情况
int* array = calloc(10, sizeof(int));

你的内存中有一个10 int的连续块,你需要一个free(array)

但你可以有一个

int** arrayOfArray = calloc(10, sizeof(int*));

现在你有一个10 int*的数组,所以指向int。在实际情况下,您的数组无法使用,您必须分配或分配数组的每个元素,例如:

for (int i = 0; i < 10; ++i)
  arrayOfArray[i] = calloc(5, sizeof(int));

因此,第一个数组的每个元素都是一个指向5 int的连续内存块的指针。在这种情况下,您有两个级别的分配,实际上您需要两个级别的解除分配,顺序相反,例如:

for (int i = 0; i < 10; ++i)
  free(arrayOfArray[i]);

free(arrayOfArray);

答案 1 :(得分:1)

操作系统通常以这种方式工作:每个内存分配在内存块中留下痕迹 - 除了您的实际/实际数据大小(其中包括一些附加信息,如分配的内存长度,下一个可用内存地址)即将到来的分配等)。具体来说,

  • 当你分配一块 40个字符时,操作系统会分配56个字节-16个字节,以便跟踪分配的内存长度,下一个可用(免费)内存地址等,实际数据为40字节。

  • 当你分配一块 40个整数时,这次,操作系统将分配176个字节,即16个字节,以便跟踪分配的内存长度,下一个可用的(免费)内存地址等,以及(4×40 =)160字节的实际数据。

因此,当你释放一个数据数组时,操作系统已经知道要释放的内存的起始和结束地址。

this视频的前20分钟非常详细地解释了该过程。

答案 2 :(得分:0)

  

但是当我们为变量数组分配内存时我们该怎么办?我们应该吗   去释放数组的每个成员[0..n],

是的,你必须free()在数组中分配的每个指针。

  

或仅仅为第一个成员释放指针是否足够?

没有

例如,

char *p[50];

for(i = 0; i<50;i++)
p[i] = malloc(10); 


for(i = 0; i<50;i++)
free(p[i]);
char **p;

p = malloc(50 * sizeof(char*));

for(i = 0; i<50;i++)
p[i] = malloc(10); 

for(i = 0; i<50;i++)
free(p[i]);

free(p);

基本上,对于malloc()的每次通话,您都可以拨打free()

答案 3 :(得分:0)

在创建变量数组时,了解您正在创建的内容非常重要。在C中,指针的作用类似于数组,因此您需要遍历整个数组,释放每个成员,然后释放第一个成员的指针。简单地将点释放到第一个成员而不释放数组的每个成员通常会导致内存泄漏,这最终可能导致程序运行缓慢并最终崩溃或修改/访问您不打算修改的数据(分段错误) )。

答案 4 :(得分:0)

你只需将指针传递给第一个元素(malloc给你的东西)即可释放:

int * array = malloc(10 * sizeof(int));
....
free(array);
相关问题