У меня проблема с освобождением памяти с помощью free () в C. Моя программа генерирует случайное генеалогическое дерево c с использованием матрицы. Эта матрица может быть очень большой в зависимости от количества членов семьи. Программа, казалось, работала нормально, пока я не решил создать более одного дерева. Я заметил, что генерация около 100 деревьев приводит к заполнению моей 8 ГБ ОЗУ! Я уверен, что смогу сделать лучший код, чтобы уменьшить потребность в памяти, но моя проблема остается. Я использую free () для освобождения памяти, и нет ошибки. Я установил Valgrind, чтобы увидеть, что происходит, и он говорит, что около 100 миллионов байт на дерево определенно потеряно. Это означает, что free () не работает нормально. Я не знаю, где проблема. Я связываю некоторые функции, которые, по моему мнению, связаны с проблемой.
typedef struct{
int f_id;
char f_name[L_NAMES];
int generations;
int n_members;
type_people *members;
int_mtx *mtx;
}type_family;
Структура выше предназначена для семьи.
typedef struct temp{
int p_id;
char name[L_NAMES];
char f_name[L_NAMES];
int generation;
int n_sons;
struct temp **sons;
int f_id;
int sex;
int age;
}type_people;
Это для членов.
typedef struct{
int i;
int j;
int **val;
}int_mtx;
И матрица. В основном я вызываю функцию для инициализации дерева:
type_family *family_a;
family_a = malloc(sizeof(type_family));
family_a = init_family_n_gen(family_a, 6);
Это первая часть init_family_n_gen ():
type_family *init_family_n_gen(type_family *family, int n){
...
family->members = malloc(max_people * sizeof(type_people));
family->mtx = mtxcalloc(family->mtx, max_people, max_people - 1);
...
Этот код для mtxcallo c, который инициализирует матрица:
int_mtx *mtxcalloc(int_mtx *mtx, int i, int j){
mtx = malloc(sizeof(int_mtx));
mtx->i = i;
mtx->j = j;
mtx->val = malloc(i * sizeof(int *));
for(int a = 0; a < i; a++){
mtx->val[a] = malloc(j * sizeof(int));
for(int b = 0; b < j; b++){
mtx->val[a][b] = 0;
}
}
return mtx;
}
И для завершения код для освобождения семейства:
void free_family(type_family *family){
for(int m = 0; m < family->n_members; m++){
if(family->members[m].n_sons != 0){
free(family->members[m].sons);
}
}
mtxfree(family->mtx);
free(family->members);
}
И один для освобождения матрицы:
void mtxfree(int_mtx *mtx){
for(int i = 0; i < mtx->i; i++){
free(mtx->val[i]);
}
free(mtx->val);
free(mtx);
}
Снимок экрана с выводом Valgrind Поэтому я вызываю free_family (family_a) каждый раз, когда мне нужно восстановить семью, но память все еще увеличивается. (На фото выше число байтов станет 1 миллиард, если я регенерирую семью в 50 раз). Спасибо за поддержку!
EDITED
Я сделал минимальный воспроизводимый пример, который имитирует мой оригинальный код. Структуры и переменные одинаковы, но я изменил функции в соответствии с Weather Vane: все они недействительны, и я передаю им двойные **. Init_family_n_gen становится:
void init_family(type_family **f){
type_family *family = malloc(sizeof(type_family));
family->members = malloc(100 * sizeof(type_people));
for(int m = 0; m < 100; m++){
family->members[m].n_sons = 0;
}
mtxcalloc(&family->mtx, 100, 99);
family->mtx->val[0][1] = 7;
family->mtx->val[9][8] = 1;
mtxrealloc(&family->mtx, 5, 4);
*f = family;
}
Основным является:
type_family *family_a;
init_family(&family_a);
free_family(&family_a);
Единственное, что я добавил, - эта функция (правильный код?):
void mtxrealloc(int_mtx **mtx, int i, int j){
(*mtx)->i = i;
(*mtx)->j = j;
(*mtx)->val = realloc((*mtx)->val, (*mtx)->i * sizeof(int *));
for(int a = 0; a < (*mtx)->i; a++){
(*mtx)->val[a] = realloc((*mtx)->val[a], (*mtx)->j * sizeof(int));
}
}
Я заметил, что проблема возникает, когда я использую функцию reallo c, и я не могу понять, почему. Я связываю изображения Valgrind с и без функции mtxreallo c. (Я вижу, что есть также 48-байтовая утечка ...). Valgrind с reallo c Valgrind без reallo c Еще раз спасибо за вашу поддержку!