Come posso liberare un intero array i cui elementi sono stati allocati individualmente in memoria tramite chiamate a malloc / calloc [duplicate]

Aug 16 2020

Da quello che so, malloc e calloc sono solo API per la contabilità nella memoria sottostante. Tenendo presente questo, mi chiedo se una chiamata a free () libererà un intero array i cui singoli elementi sono stati allocati in memoria tramite chiamate indipendenti a malloc (o calloc).

Esatto, ho il seguente codice:

int *num,* num_start;

num_start=num;

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

free(num_start);

Libererà free(num_start)l'intero array di N elementi interi a cui è stato allocato dinamicamente spazio, indipendentemente?

Risposte

1 P__JsupportswomeninPoland Aug 16 2020 at 10:09

Il "codice" che hai postato non ha alcun senso ed è sbagliato.

int *num, num_start;
num_start=num;

num_start è un numero intero non un puntatore.

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

ad essere onesto non capisco cosa dovrebbe fare questo codice, ma di sicuro è sbagliato

se vuoi allocare memoria per Ninteri

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

e per liberarti hai solo bisogno

free(num);

O se vuoi allocare un puntatore per memorizzare N puntatori in N interi

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);
}

Quando si alloca la memoria è necessario verificare se l'operazione è andata a buon fine. Questi controlli non sono inclusi nell'esempio per rendere il codice più facile da leggere.

tadman Aug 16 2020 at 09:55

Le funzioni calloc()e malloc()restituiscono un puntatore all'allocazione che funge anche da handle per rilasciare quella memoria. Sebbene tu sia libero di fare copie di quel puntatore e manipolarle come meglio credi, quando chiami free()devi fornire il valore originale .

Vale a dire che funziona:

// 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);

Puoi anche diventare un po 'avventuroso, purché torni alla tua destinazione originale:

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

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

free(x);

Dove qui xè tornato al suo valore originario dopo un breve viaggio. Nella pratica generale è meglio preservare il puntatore originale che doverlo ricostruire in seguito. Fai delle copie se intendi manipolarle.