如何使用malloc释放二维数组

我有一个有6个元素的数组。 这6个元素中的每一个都有40个元素。 我想知道当我释放malloced内存,我是否必须释放两者或者我可以释放主层(包含6个元素的那个)这将自动释放其他二级arrays吗?

char ** listofdetails; //FIRST ARRAY listofdetails = malloc(sizeof(char*)*6); for(i=0;i<6;i++) { listofdetails[i] = malloc(sizeof(char)*40); // SECONDARY ARRAY fgets(listofdetails[i], 40, fp); } 

你需要像破坏这样的破坏function

  void destroy_array_of_cstrings (char**lis, size_t siz) { if (!lis) return; for (size_t ix=0; ix 

你将在你的案例中调用destroy_array_cstring(listofdetails, 6) 。 正如Alfred Hang回答的那样 ,你应该在以下之后立即清除listofdetailslistofdetails=NULL; 避免意外free指针两次,或取消引用释放的指针。

你最好使用calloc来分配一个指针数组(你真的希望它们中的每一个都被初始化为NULL ,而calloc在实践中calloc )。

另请参阅这个问题的答案 ,同时也提到listeofdetails带有6的listeofdetails (所以我猜它是相同的功课)。

顺便说一下,你可能以后会使用Boehm的保守垃圾收集器 :你会使用GC_MALLOCGC_STRDUP ,你不会再费心去免费了。 和老师讨论一下。

经验法则:对于每个malloc都有免费的。

您必须提供一个类似的循环,在释放字符串数组之前释放每个单独的字符串。

除了Basile的答案之外,为了避免在释放每个数组条目后有悬空指针,最好立即将指针设置为null。

参考: free()

不,辅助arrays不会自动释放; 释放listofdetails 之前,您需要明确free它们:

 for ( i = 0; i < 6; i++ ) free( listofdetails[i] ); free( listofdetails ); 

对于每个malloc必须有一个free ,并且必须以malloc调用的相反顺序执行free调用。

如果在编译时1知道列数,则可以在一个malloc调用中分配整个内容,如下所示:

 char (*listofdetails)[40] = malloc( sizeof *listofdetails * 6 ); 

这在一次调用中分配一个6x40的char数组。 您使用它的方式与上面几乎相同:

 fgets( listofdetails[i], sizeof listofdetails[i], fp ); 

listdetails[i]的类型是“40个元素的char数组”,因此sizeof listdetails[i]将给我们与sizeof (char) * 40相同的结果(请注意, 这只有效,因为我将listofdetails声明为指向一个40元素的char数组,而不是指向char的指针。

这还具有以下优点:所有行在存储器中彼此相邻,这对于某些情况可能是重要的。 对于两步分配方法,情况不一定如此。

这只需要一个free电话:

 free( listofdetails ); 

但是你们可能还没有讨论过指向数组的指针。


1.如果您正在使用仍支持可变长度数组的C99编译器或C2011编译器,您仍然可以使用单个malloc调用,如下所示:

 size_t rows, cols; ... char (*listofdetails[cols]) = malloc( sizeof *listofdetails * rows ); ... free( listofdetails ); 

否则,您将不得不像在代码中那样进行零碎分配。

如果你想像这样访问listofdetails[i][j] ,那么是的,你需要malloc内部数组。 你也必须单独释放它。

如果您知道内部数组大小并且它是固定的,那么您可以listofdetails[i * width + j]所有内容(宽度*高度)并像这样访问它: listofdetails[i * width + j]

你需要释放两个,因为free free函数不会自动释放第二个数组。

像这样免费:

 for(i=0;i<6;i++) { free(listofdetails[i]); } free(listofdetails); 

在为这个aaray动态分配内存之后,当需要释放其中一个动态分配的多维“数组”时,我们必须记住释放我们分配的每个内存块。 (只是释放顶级指针,数组,不会削减它;如果我们这样做,所有二级指针都会丢失但不会被释放,并且会浪费内存。)以下是代码的外观:

 for(i = 0; i < nrows; i++) free(array[i]); free(array); 

对于你的情况应该是:

 for ( i = 0; i < 6; i++ ) free( listofdetails[i] ); free( listofdetails );