2015-10-11 22 views
2

我真的很困惑这个二维字符数组如何正确释放字符**用C

char **arg = malloc(sizeof(char*) * argc) 
for (int i = 0; i < argc; i++) 
    arg[i] = malloc(sizeof(char) * size) 
... 
... 

现在假设经过一系列的操作,我忘了变量的argc,我怎么能释放那些记忆? 我可以做这样的事吗?在所有情况下,这绝对正确吗?

char **tmp = arg; 
while (*tmp != NULL){ 
    free(*tmp); 
    tmp++; 
} 
free(arg); 
+0

数组不是NULL,只对字符串有效(char *在C中) – John

+0

实际上为char *数组分配内存,然后为数组中的每个项分配内存。你必须先释放物品然后释放它自己的阵列。 – milevyo

+0

这实际上并不是一个坏主意,但你应该在数组的末尾明确地加上NULL。我在很多情况下都使用它,这很好。 –

回答

3

没有

while(*tmp != NULL){ 

你可以达到零上,您将间接引用的内存还没有被分配到并引发未定义行为的一个点。

或如建议您可以明确地指定一个NULL到最后分配的指针,在这种情况下,它将工作。

+0

在这种情况下,释放这些指针的正确方法是什么? –

+1

@lplouis:跟踪有多少指针分配给内存 –

+0

,所以argc一定不能被遗忘? –

-1

,如果你定义的char *数组是这样的:

char **arg = calloc(1, sizeof(char *) * argc);

你可以确保每一个未定义的指针将等于NULL

,然后你可以使用while循环几乎像你建议:

char *tmp = *arg; 
while (tmp != NULL) { 
    free(tmp); 
    tmp++; 
} 
free(arg); 
0

正如其他人所说的,如图所示的循环中释放的问题是一个额外的项目(argc + 1)需要被分配并且它必须被设置为NULL。另一种技术是第一分配空间的指针,你已经做了

char **arg = malloc(sizeof(char*) * argc) 

然后,如果你知道所有的后续项目的大小相同,在一个巨大的块分配,并设置其余元素在间隔的偏移

arg[0] = malloc(sizeof(char) * size * argc); 
for (int i = 1; i < argc; ++i) 
    arg[i] = arg[i - 1] + size; 

从而释放空间是不费吹灰之力:没必要还记得ARGC

free(arg[0]); /* this will free the memory used by all the elements */ 
free(arg); 

大缺点这种方法是,如果任何的数组元素溢出,它会破坏下一个项目。除非它是最后一个项目,否则这不能通过堆检查轻松检测到。