Распределение памяти в массивах

Я сделал программу, которая открывает файл (чтение в двоичном формате) и сохраняет все слова (в файле) в массиве 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 */
    

    Как нужно выделить xchar* указатели для 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++) вместо.

Другие вопросы по тегам