释放数组中的结构时双重释放
double free when freeing structure in array
我正在逐行读取文件(该文件只包含一行用于测试),我正在为每一行创建一个 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] = '[=10=]';
}
Person *person = NULL;
person_create(&person, line_num, 2, line);
persons[line_num] = *person;
line_num++;
}
free(line);
printf("lines read %d\n", 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;
但我似乎无法理解到底出了什么问题。
您正在丢失 malloc()
ed 内存,因为您将它复制到您的实际结构数组 (persons
) 中。您的代码不需要使用 malloc()
,当然也不需要像它那样使用 free()
。
拥有一个指针数组会更有意义:
Person *persons[10];
然后有函数调用malloc()
return新分配的内存,这样就可以persons[line_num] = person_create(line_num, 2, line);
了。 然后你需要通过并free()
他们全部。
您的程序有一些严重的未定义行为:一旦 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;
这会导致越界内存访问,进而调用 undefined behaviour。
我正在逐行读取文件(该文件只包含一行用于测试),我正在为每一行创建一个 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] = '[=10=]';
}
Person *person = NULL;
person_create(&person, line_num, 2, line);
persons[line_num] = *person;
line_num++;
}
free(line);
printf("lines read %d\n", 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;
但我似乎无法理解到底出了什么问题。
您正在丢失 malloc()
ed 内存,因为您将它复制到您的实际结构数组 (persons
) 中。您的代码不需要使用 malloc()
,当然也不需要像它那样使用 free()
。
拥有一个指针数组会更有意义:
Person *persons[10];
然后有函数调用malloc()
return新分配的内存,这样就可以persons[line_num] = person_create(line_num, 2, line);
了。 然后你需要通过并free()
他们全部。
您的程序有一些严重的未定义行为:一旦 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;
这会导致越界内存访问,进而调用 undefined behaviour。