ОК, есть большая путаница, объясняющая, в каком именно порядке
необходимо free()
звонки должны быть, поэтому я постараюсь уточнить, что
люди пытаются понять и почему.
Начиная с основ, чтобы освободить память, которая была выделена
используя malloc()
, вы просто вызываете free()
точно с указателем
который вы дали malloc()
. Итак, для этого кода:
int **a = malloc(m * sizeof(int *));
вам нужно соответствие:
free(a);
и для этой строки:
a[i]=malloc(n * sizeof(int));
вам нужно соответствие:
free(a[i]);
внутри аналогичного цикла.
Где это усложняется, это порядок, в котором это должно произойти. Если
Вы звоните malloc()
несколько раз, чтобы получить несколько разных кусков
память, в общем, не имеет значения, в каком порядке вы звоните free()
, когда
Вы сделали с ними. Тем не менее, порядок здесь важен для очень
конкретная причина: вы используете один кусок памяти malloc
ed для хранения
указатели на другие фрагменты malloc
ed памяти. Потому что вы должны
не попытка чтения или записи памяти после того, как вы вернули ее обратно
free()
, это означает, что вам придется освободить куски с
их указатели хранятся в a[i]
до , и вы освобождаете сам блок a
.
Отдельные чанки с указателями, хранящиеся в a[i]
, не зависят от каждого
другой, и так может быть free
d в любом порядке.
Итак, сложив все это вместе, мы получим:
for (i = 0; i < m; i++) {
free(a[i]);
}
free(a);
Последний совет: при вызове malloc()
рассмотрите возможность изменения этих параметров:
int **a = malloc(m * sizeof(int *));
a[i]=malloc(n * sizeof(int));
до:
int **a = malloc(m * sizeof(*a));
a[i]=malloc(n * sizeof(*(a[i])));
Что это делает? Компилятор знает, что a
является int **
, поэтому он может
определите, что sizeof(*a)
совпадает с sizeof(int *)
. Однако если
позже вы передумаете и захотите char
с или short
с или long
с или
что угодно в вашем массиве вместо int
s, или вы адаптируете этот код на потом
использовать что-то еще, вам придется изменить только один оставшийся
ссылка на int
в первой приведенной выше строке и все остальное
автоматически встанет на свое место для вас. Это исключает вероятность
незаметных ошибок в будущем.
Удачи!