Alocação dinâmica de memória

A memória heap é uma área de memória usada para alocação dinâmica de memória durante a execução de um programa. Ao contrário da memória stack, que é usada para armazenar variáveis locais de função com um tempo de vida limitado, a memória heap é usada para armazenar dados que podem persistir além do escopo de uma função ou bloco de código.

A alocação dinâmica de memória em C é uma técnica importante para alocar e liberar blocos de memória na memória heap durante a execução de um programa. Isso permite que você aloque a quantidade exata de memória necessária para armazenar dados, o que é especialmente útil quando você não sabe antecipadamente o tamanho exato dos dados que precisa armazenar.

A alocação dinâmica de memória pode levar a vazamentos de memória (memory leaks) se não for usada corretamente.

NOTA: Um esgotamento de memória pode ocorrer quando alocamos sucessivos blocos de memória que depois não libertamos. Isto pode levar a um esgotamento da memória disponível.

A alocação dinâmica é feita com o uso das funções malloc, calloc e realloc e free que pertencem à biblioteca stdlib.h.

  • Função malloc: aloca um bloco de memória.
  • Função calloc: aloca um bloco de memória e preenche-o a zeros.
  • Função realloc: realoca um bloco de memória já alocado mas com um novo tamanho.
  • Função free: liberta um bloco de memória alocado.

As funções malloc, calloc e realloc recebem o tamanho da memória a alocar em bytes e retornam um ponteiro para o inicio do bloco de memória alocado. Se não houver memória disponível retornam null.

Alocação de memória

A função malloc (Memory Allocation) aloca um bloco de memória de forma dinâmica. A sintaxe é a seguinte:

tipo *ptr = (tipo *)malloc(tamanho_do_bloco);

tipo é o tipo de dado que desejamos armazenar na memória alocada.

Exemplo:

int *numeros;
numeros = (int *)malloc(5 * sizeof(int)); // Aloca espaço para um array de 5 inteiros

if (numeros == NULL) {
    printf("Falha na alocação de memória.");
    exit(1);
}

Alocação de memória com calloc

A função calloc (Contiguous Allocation) é semelhante à malloc, mas ela inicializa todos os bytes alocados com zero. A sintaxe é a seguinte:

tipo *ptr = (tipo *)calloc(numero_de_elementos, tamanho_de_cada_elemento);

Exemplo:

double *valores;

// Aloca espaço para um array de 10 doubles inicializados com 0.0:

valores = (double *)calloc(10, sizeof(double)); 

if (valores == NULL) {
    printf("Falha na alocação de memória.");
    exit(1);
}

Realocação de memória com realloc

A função realloc (Reallocate) permite redimensionar uma área de memória previamente alocada. Ela recebe um ponteiro para a memória previamente alocada, o novo tamanho em bytes e retorna um novo ponteiro para a memória redimensionada.

É comum usar realloc quando precisamos aumentar ou diminuir o tamanho de uma estrutura de dados dinâmica, como um array dinâmico.

A sintaxe é a seguinte:

tipo *novo_ptr = (tipo *)realloc(ptr_existente, novo_tamanho_em_bytes);

Exemplo:

int *numeros = (int *)malloc(5 * sizeof(int)); // Aloca espaço para um array de 5 inteiros

// Redimensiona para um array de 10 inteiros
numeros = (int *)realloc(numeros, 10 * sizeof(int));

if (numeros == NULL) {
    printf("Falha na realocação de memória.");
    exit(1);
}

Libertação de memória alocada

A função free é usada para libertar a memória previamente alocada no heap. Ela não altera o conteúdo da memória; em vez disso, marca a memória como disponível para reutilização.

Sempre que alocarmos memória dinamicamente, é uma boa prática libertá-la quando não for mais necessária para evitar vazamentos de memória.

A sintaxe é a seguinte:

free(ptr);

Exemplo:

int *numeros = (int *)malloc(5 * sizeof(int)); // Aloca espaço para um array de 5 inteiros

// ... usa a memória alocada

free(numeros); // Liberta a memória quando não for mais necessária