如何在C中正确释放char **

时间:2015-10-11 13:00:25

标签: c pointers

我真的对这个2D字符数组感到困惑

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);

3 个答案:

答案 0 :(得分:3)

没有

while(*tmp != NULL){

您可能会超出一个点,在这一点上您将取消引用尚未分配的内存并触发未定义的行为。

或者按照建议你可以明确地将NULL分配给最后分配的指针,在这种情况下它将起作用。

答案 1 :(得分: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);

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

答案 2 :(得分:-1)

如果您像这样定义char *数组:

#include <stdio.h> int main(void) { int semester_1, grade_1, grade_2, grade_3, subtotal; /* Better to use an array */ double total_marks, average; printf("Enter number of semester you to check"); scanf("%d", &semester_1); while (semester_1 > 0) { printf("Enter marks for first subject"); scanf("%d", &grade_1); printf("Enter marks for second subject"); scanf("%d", &grade_2); printf("Enter marks for third subject"); scanf("%d", &grade_3); subtotal = grade_1 + grade_2 + grade_3; total_marks = (double)subtotal / 300 * 100; /* Note the cast */ printf("Your average this semester is %f", total_marks); /* Note the change in the format specifier */ semester_1--; } average = (double)semester_1 / 100 * total_marks; /* Note the cast */ printf("Your final average for all semesters is %f", average); /* Note the change in the format specifier */ }

你可以确定每个未定义的指针都等于NULL

然后你可以像你建议的那样使用while循环:

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