Como faço para liberar uma matriz inteira cujos elementos foram alocados individualmente na memória por meio de chamadas para malloc / calloc [duplicado]

Aug 16 2020

Pelo que eu sei, malloc e calloc são apenas APIs de manutenção de livros na memória subjacente. Mantendo isso em mente, eu me pergunto se uma chamada para free () irá liberar um array inteiro cujos elementos individuais foram alocados na memória por meio de chamadas independentes para malloc (ou calloc).

Precisamente, tenho o seguinte código:

int *num,* num_start;

num_start=num;

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

free(num_start);

Irá free(num_start)liberar todo o array de N elementos inteiros que foram alocados dinamicamente no espaço, independentemente?

Respostas

1 P__JsupportswomeninPoland Aug 16 2020 at 10:09

O "código" que você postou não faz sentido e está errado.

int *num, num_start;
num_start=num;

num_start é um inteiro, não um ponteiro.

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

para ser honesto eu não entendo o que esse código deve fazer, mas com certeza está errado

se você deseja alocar memória para Ninteiros

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

e para libertar você só precisa

free(num);

Ou se você deseja alocar um ponteiro para armazenar N ponteiros para N inteiros

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

Ao alocar memória, você deve verificar se a operação foi bem-sucedida. Essas verificações não estão incluídas no exemplo para tornar o código mais fácil de ler.

tadman Aug 16 2020 at 09:55

As funções calloc()e malloc()retornam um ponteiro para a alocação que funciona como um identificador para liberar essa memória. Embora você esteja livre para fazer cópias desse ponteiro e manipulá-los como achar adequado, ao ligar para free()você deve fornecer o valor original .

Isso quer dizer que funciona:

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

Você também pode se aventurar um pouco, contanto que volte ao seu destino original:

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

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

free(x);

Onde aqui xvoltou ao seu valor original após uma curta viagem. Na prática geral, é melhor preservar o ponteiro original do que reconstruí-lo posteriormente. Faça cópias se tiver a intenção de manipulá-los.