我逐行读取一个文件(该文件只包含一行用于测试),并为每行创建一个struct
,并将该struct
添加到预定义的数组中。
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
typedef struct {
int age;
int weight;
char *name;
} Person;
int person_create(Person **person, unsigned int age, unsigned int weight, char *name)
{
*person = malloc(sizeof(Person));
if (person == NULL) {
return 0;
}
return 1;
}
void person_free(Person *person)
{
free(person);
return;
}
int main(void)
{
FILE *input_file = NULL;
input_file = fopen("names.txt", "r");
assert(input_file != NULL);
char *line = NULL;
size_t _ = 0;
ssize_t line_len = 0;
Person persons[1] = {};
int line_num = 0;
while ((line_len = getline(&line, &_, input_file)) != -1) {
if (line[line_len - 1] == 'n') {
line[line_len - 1] = ' ';
}
Person *person = NULL;
person_create(&person, line_num, 2, line);
persons[line_num] = *person;
line_num++;
}
free(line);
printf("lines read %dn", line_num);
for (int i = 0; i < 1; i++) {
person_free(&persons[i]);
}
return 0;
}
我尽可能地精简了程序,但在释放数组条目时,我得到了一个错误
*** Error in `./prog': double free or corruption (out): 0x00007fff7ace9f10 ***
Aborted (core dumped)
如果我省略了对free_person
的调用,则valgrind
报告内存丢失。
我很确定这与我如何将每一行的人分配给阵列有关
Person *person = NULL;
person_create(&person, line_num, 2, line);
persons[line_num] = *person;
但我似乎不明白到底出了什么问题。
您的程序有一些严重的未定义行为:一旦line_num
达到零以上,您就要在persons[]
数组外写入内存。您需要分配足够的元素,并使其成为指针数组:
Person *persons[100]; // or some other MAX
一旦将persons[]
设置为指针数组,就可以清楚地了解free(&persons[i])
和persons[line_num] = *person
不正确的原因(编译器应该为赋值发出警告)。
此外,malloc
结果的检查不正确:
if (person == NULL) {
return 0;
}
您应该检查*person
,而不是person
,因为person
是双指针。
您的代码显示了未定义的行为。您已标记
Person persons[1] = {};
稍后,您将使用
persons[line_num] = *person;
这会导致超出绑定的内存访问,进而调用未定义的行为。
您正在丢失malloc()
ed内存,因为您将其复制到实际结构的数组(persons
)中。您的代码不需要使用malloc()
,当然也不需要像它那样使用free()
。
有一个指针数组会更有意义:
Person *persons[10];
然后让调用malloc()
的函数返回新分配的内存,这样就可以执行persons[line_num] = person_create(line_num, 2, line);
了然后你需要遍历并free()
它们。