Распределение памяти в массивах
Я сделал программу, которая открывает файл (чтение в двоичном формате) и сохраняет все слова (в файле) в массиве char (динамически распределяется по длине слова).
Это код:
char **leggi_stringhe(const char *filename, size_t *size) {
FILE *f = fopen(filename, "rb");
if (f == NULL) {
*size = 0;
return NULL;
}
int x;
if (fread(&x, 1, 4, f) != 4) {
*size = 0;
return NULL;
}
char **stringhe = malloc((x) * sizeof(char));
for (int i = 0; i < x; i++) {
int z = 0;
if (fread(&z, 1, 4, f) != 4) {
*size = 0;
return NULL;
}
stringhe[i] = malloc((z)* sizeof(char));
if (fread(stringhe[i], 1, z, f) != z) {
*size = 0;
return NULL;
}
stringhe[i][z] = 0;
}
*size = x;
fclose(f);
return stringhe;
}
int main(void) {
size_t t;
char **a = leggi_stringhe("file1.bin", &t);
for (int i = 0; i < t; i++)
free(a[i]);
free(a);;
}
Программа работает, но у меня проблемы с освобождением памяти. После вызова функции leggi_stringhe переменная a содержит:
a[0] = "first"
a[1] = "second"
a[2] = "third"
но когда я пытаюсь освободить целую переменную, как я написал, отладчик останавливается с предупреждением.
Этот вопрос меня вдохновил на написание кода с использованием динамического выделения памяти для массивов, но я не понимаю, почему я получаю эту ошибку, когда пытаюсь освободить память.
2 ответа
Ваш начальный звонок malloc
неправильно. Вы выделяете место для x
символы, а не для указателей на char
,
Ваш второй вызов внутри цикла неверен, так как вы не выделяете место для терминатора.
Наконец, и не имеет отношения к проблемам, о которых вы спрашиваете, но если fread
вызовы внутри цикла не удаются, у вас будут утечки памяти.
Есть некоторые проблемы с вашим кодом:
Эта строка:
char **stringhe = malloc((x) * sizeof(char));
Должно быть:
char **stringhe = malloc((x) * sizeof(char*)); /* or sizeof *stringhe */
Как нужно выделить
x
char*
указатели дляstringhe
,Внутри вашего первого цикла for вы не добавляете
+1
для нулевого терминатора. Это должно быть вместо:stringhe[i] = malloc(z+1); /* sizeof(char) = 1 */
Вам необходимо проверить возврат
malloc()
, Может вернутьсяNULL
если неудачно. Вы можете сделать это, просто проверивif (ptr == NULL)
, затем выйдите из программы. Было бы небезопасно допустить неудачногоmalloc()
продолжить в программе.for (int i = 0; i < t; i++)
сравниваетint
сsize_t
, Это должно бытьfor (size_t i = 0; i < t; i++)
вместо.