Ответ 1
Хорошо, там есть путаница, объясняющая, какой именно порядок
необходимо, чтобы были вызовы 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
в первой цитируемой строке выше, и все остальное
автоматически встанет на свои места. Это устраняет вероятность
незаметных ошибок в будущем.
Удачи!