Alocação dinâmica de vetor

Esta página não introduz nenhum conteúdo especial, apenas exemplifica como a alocação dinâmica de memória pode ser utilizada para a alocação de um vetor.

Se você ainda não fez a leitura do conteúdo sobre alocação dinâmica de memória, volte uma casa ;)

👀 Parece igual, mas é diferente

Em AED 1, aprendemos a declarar vetores da seguinte forma:

int vetor[4];

No entanto, na página anterior, compreendemos que a alocação de dinâmica memória (com malloc ou calloc) pode ser utilizada para apenas uma variável ou um conjunto de espaços de memória. Descobrimos, portanto, uma outra forma de declarar um vetor.

Acontece que, embora o resultado pareça o mesmo, há uma importante diferença entre eles:

int vetorAlocEstatica[4];
int *vetorAlocDinamica = (int*) calloc(4, sizeof(int));

🏃🏽‍♂️ Percorrendo o vetor

Mesmo que o vetor tenha sido alocado de forma dinâmica, podemos percorrê-lo utilizando colchetes, como fazemos tradicionalmente. Também podemos, sem qualquer problema, percorrer o vetor usando artimética de ponteiros.

No código abaixo, usei as duas estratégias para mostrar que ambas funcionam:

#include <stdio.h>
#include<stdlib.h>

int main()
{
    int *vetorAlocDinamica = (int*) calloc(4, sizeof(int));
    
    /* Percorrendo com colchetes */
    vetorAlocDinamica[0] = 7;
    vetorAlocDinamica[1] = 14;
    vetorAlocDinamica[2] = 21;
    vetorAlocDinamica[3] = 28;
    
    /* Percorrendo com aritmética */
    for(int i = 0; i < 4; i++){
        printf("[%d] => %d\n", i, *(vetorAlocDinamica+i));
    }

    /* Desalocar a memória */
    free(vetorAlocDinamica);
    
    /* Corrigir o ponteiro */
    vetorAlocDinamica = NULL;
    
    return 0;
}

Após percorrer o vetor para impressão, duas operações importantes são feitas: a liberação do espaço de memória ocupado pelo vetor, por meio da função free, e o tratamento do ponteiro vetorAlocDinamica, que agora aponta para uma posição inválida de memória.

📦 Mudando o tamanho do vetor

Quando declaramos um vetor com alocação estática de memória, o seu tamanho não pode ser alterado posteriormente. Quando usamos a alocação dinâmica, temos essa possibilidade graças à função realloc. Vamos acompanhar como um vetor pode ter seu tamanho alterado em tempo de execução:

#include <stdio.h>
#include<stdlib.h>

int main()
{
    int *vetorAlocDinamica = (int*) calloc(4, sizeof(int));
    
    /* Percorrendo com colchetes */
    vetorAlocDinamica[0] = 7;
    vetorAlocDinamica[1] = 14;
    vetorAlocDinamica[2] = 21;
    vetorAlocDinamica[3] = 28;
    
    /* Aumentando o tamanho */
    int *novoEnd = (int*) realloc(vetorAlocDinamica, 7 * sizeof(int));


    /* Checando se houve movimentação */
    novoEnd != vetorAlocDinamica ? printf("Mudou de local.\n") : printf("Aumentou sem mudar de local.\n");

    /* Atualizar o ponteiro original */
    if(novoEnd!=NULL){
        vetorAlocDinamica = novoEnd;
    }
    
    /* Percorrendo com aritmética */
    for(int i = 0; i < 7; i++){
        printf("[%d] => %d\n", i, *(vetorAlocDinamica+i));
    }    
    
    /* Desalocar a memória */
    free(vetorAlocDinamica);
    
    /* Corrigir o ponteiro */
    vetorAlocDinamica = NULL;
    
    return 0;
}