Comment libérer un tableau entier dont les éléments ont été individuellement alloués en mémoire via des appels à malloc / calloc [duplicate]

Aug 16 2020

D'après ce que je sais, malloc et calloc ne sont que des API de comptabilité sur la mémoire sous-jacente. En gardant cela à l'esprit, je me demande si un appel à free () libérera un tableau entier dont les éléments individuels ont été alloués de mémoire via des appels indépendants à malloc (ou calloc).

Justement, j'ai le code suivant:

int *num,* num_start;

num_start=num;

for(i=0;i<N;i++)
{
    num = (int *)calloc(0, sizeof(int));
    num++;
}

free(num_start);

Libérera free(num_start)- t -il le tableau entier de N éléments entiers qui ont été alloués dynamiquement, indépendamment?

Réponses

1 P__JsupportswomeninPoland Aug 16 2020 at 10:09

Le "code" que vous avez publié n'a aucun sens et est faux.

int *num, num_start;
num_start=num;

num_start est un entier et non un pointeur.

for(i=0;i<N;i++)
{
    num = (int *)calloc(0, sizeof(int));
    num++;
}

pour être honnête, je ne comprends pas ce que ce code est censé faire, mais c'est certainement faux

si vous souhaitez allouer de la mémoire pour les Nentiers

int *num = calloc(N, sizeof(*num));

et pour vous libérer, il vous suffit

free(num);

Ou si vous souhaitez allouer un pointeur pour stocker N pointeurs vers N entiers

int **allocate(size_t N)
{
    int **num = malloc(N * sizeof(*num));
    for(size_t i=0; i<N; i++)
    {
        num[i] = calloc(N, sizeof(**num));
    }
    return num;
}

void arrayfree(int **num, size_t size)
{
    for(size_t i = 0; i < size; i++)
    {
        free(num[i]);
    }
    free(num);
}

Lorsque vous allouez de la mémoire, vous devez vérifier si l'opération a réussi. Ces vérifications ne sont pas incluses dans l'exemple pour rendre le code plus facile à lire.

tadman Aug 16 2020 at 09:55

Les fonctions calloc()et malloc()renvoient un pointeur vers l'allocation qui sert également de handle pour libérer cette mémoire. Alors que vous êtes libre de faire des copies de ce pointeur et de les manipuler comme bon vous semble, lorsque vous appelez, free()vous devez fournir la valeur d' origine .

C'est-à-dire que cela fonctionne:

// Original allocation
int* x = calloc(42, sizeof(int));

// Making a new (independent) copy of the pointer to a new pointer
int* p = x;

// Arbitrary pointer manipulation and mangling
x++;

// Freeing with the copied value
free(p);

Vous pouvez également devenir un peu aventureux, tant que vous revenez à votre destination d'origine:

int* x = calloc(42, sizeof(int));

x += 40;
x -= 30;
x += 10;
x -= 13;
x -= 7;

free(x);

Où ici xa retrouvé sa valeur d'origine après un court voyage. En pratique générale, il vaut mieux conserver le pointeur d'origine que de devoir le reconstruire plus tard. Faites des copies si vous avez l'intention de les manipuler.