【问题标题】:C - How to correctly free memory of a pointer to array of n char ((*p)[n])?C - 如何正确释放指向 n char ((*p)[n]) 数组的指针的内存?
【发布时间】:2015-04-09 06:09:58
【问题描述】:

我编写了以下程序来从文件中读取字符串并将它们存储到数组中,这些数组在结构中具有固定的列数和可变的行数。

FILE *fp;
typedef struct {
char  (*date)[12],
      (*content)[50],
      (*amount)[10];
} list;
list in;
int i,lines;
fp = fopen("book.txt","r");
lines = 100;
in.date = malloc(lines * 12 * sizeof(char));
in.content = malloc(lines * 50 * sizeof(char));
in.amount = malloc(lines *10* sizeof(char ));

printf("%-12s%-40s%-10s\n","Date","Content","Amount");

for(i = 0;i <lines;i++){
    fscanf(fp,"%s\t%[a-z|A-Z| ]\t%s\n",in.date[i],in.content[i],in.amount[i]);
    printf("%-12s%-40s%-10s%\n",in.date[i],in.content[i],in.amount[i]);
}

我可以为行分配内存,但是当释放内存时程序将停止工作,如下所示:

for(i = 0;i < lines;i++){
        free(in.date[i]);
        free(in.content[i]);
        free(in.amount[i]);
    }

如何正确地将它们从内存中释放出来?

【问题讨论】:

  • 如果你分配in.date,为什么要释放in.date[i]

标签: c arrays pointers memory memory-management


【解决方案1】:

您正在分配一个 array 事物,但试图释放每个 individual 事物,而您需要做的是释放 array。

通常,清理意味着释放您分配的每个对象(如果它们之间有任何交叉链接,则按相反的顺序)。如果该对象是一个数组,则释放该数组。不要尝试释放数组的一部分。

根据C11 7.22.3.3 The free function /2

...如果参数与内存管理函数先前返回的指针不匹配,...行为未定义。

这意味着您需要执行以下操作:

in.date = malloc (lines * 12);    // sizeof(char) is ALWAYS 1
in.content = malloc (lines * 50); //   so TOTALLY unnecessary.
in.amount = malloc (lines * 10);
:
// use them here
:
free (in.amount);
free (in.content);
free (in.date);

您可能还应该检查每个分配,看看它是否也失败了,因为在这种情况下继续可能会造成很大的痛苦。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-18
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多