Две вещи, которые нужно знать:
- У вас есть две области памяти (чтобы было легче понять) куча и стек
- malloc, realloc, calloc выделяют ресурсы из кучи. Я скажу только malloc (но это то же самое)
- бесплатно можно освободить только ресурсы из кучи. Стек является резервным для компилятора (он хранит вызов функции и другие данные)
Правило для каждого ресурса, который вы получаете от malloc, вы должны его освобождать.
для освобождения просто вызовите функцию free (но мы можем дополнительно присвоить нулевой указатель, чтобы убедиться, что он освобожден).
char * a = malloc(255);
бесплатно
free(a);/* this is mandatory */
a = NULL;/* we can add this to the first line */
На самом деле, если вы привыкли присваивать значение NULL, и когда вы получите доступ к его значению, у вас будет ошибка отсчета NULL: так вы будете знать, где найти ошибку
Что вы пытаетесь сделать:
выделите массив char ** arr = malloc(nrows * sizeof(char *));
и вы освободите его free(arr);
но вы выделяете 20 массивов char arr[i] = malloc(ncolumns * sizeof(char));
вы игнорируете его значение arr[0] = "string1";
(вы теряете значение, возвращаемое malloc, поэтому вы не можете освободить теперь arr [0]), мы не на C ++. Таким образом, «string1» хранится в стеке (поэтому malloc не может его освободить)
и вы звоните бесплатно.
что вы можете сделать
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int nrows = 20; int ncolumns = 10;
char ** arr = malloc(nrows * sizeof(char *));
for(int i = 0; i < nrows; i++)
arr[i] = malloc(ncolumns * sizeof(char));
free(arr[0]);//know we can loose it value because it is freed
arr[0] = NULL;// in fact we assign a value just after so this line is useless but is educationnal purpose
free(arr[1]);//know we can loose it value because it is freed
arr[1] = NULL;// in fact we assign a value just after so this line is useless but is educationnal purpose
arr[0] = "string1";
arr[1] = "string2";
// does not work without the following code:
// for(int i = 0; i < 20; i++)
// arr[i] = NULL;
for(int i = 2; i < 20; i++)//we start at 2 because the first two value are on the stack
{
free(arr[i]);
arr[i] = NULL;//this is useless because we will free arr just after the loop)
}
free(arr);
arr = NULL;// this is useless because we exit the end of program
return 0;
}