Médio C

Redimensionamento com realloc

Enunciado

Crie um programa que leia um número inteiro n do usuário, aloque dinamicamente um vetor de n inteiros, preencha-o com valores de 0 a n-1 e depois redimensione-o para 2*n elementos usando realloc. Preencha os novos elementos com valores de n a 2*n-1 e exiba todo o vetor. Libere a memória ao final.

Requisitos

  • Ler n do usuário.
  • Alocar com malloc e verificar erro.
  • Usar realloc para dobrar o tamanho.
  • Preencher e exibir todos os 2*n elementos.
  • Liberar a memória.

Código inicial

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

int main(void) {
    int n;
    printf("Digite n: ");
    scanf("%d", &n);
    // Seu código aqui
    return 0;
}

Saída esperada

Digite n: 5
0 1 2 3 4 5 6 7 8 9
Ver dica

Após realloc, use o novo ponteiro. Se realloc falhar, o ponteiro original ainda é válido e deve ser liberado.

Mostrar solução
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int n;
    printf("Digite n: ");
    scanf("%d", &n);

    // Aloca vetor de n inteiros
    int *vetor = malloc(n * sizeof(int));
    if (vetor == NULL) {
        printf("Erro: malloc falhou\n");
        return 1;
    }

    // Preenche com 0 a n-1
    for (int i = 0; i < n; i++) {
        vetor[i] = i;
    }

    // Redimensiona para 2*n elementos
    int *novo_vetor = realloc(vetor, 2 * n * sizeof(int));
    if (novo_vetor == NULL) {
        printf("Erro: realloc falhou\n");
        free(vetor); // libera o bloco original
        return 1;
    }
    vetor = novo_vetor;

    // Preenche os novos elementos
    for (int i = n; i < 2 * n; i++) {
        vetor[i] = i;
    }

    // Exibe todos os 2*n elementos
    for (int i = 0; i < 2 * n; i++) {
        printf("%d ", vetor[i]);
    }
    printf("\n");

    // Libera a memória
    free(vetor);
    return 0;
}

Passo a passo

  1. Lemos n com scanf.
  2. Alocamos n * sizeof(int) bytes com malloc e verificamos se o retorno é NULL.
  3. Preenchemos as posições 0 a n-1 com os valores correspondentes.
  4. Chamamos realloc para expandir o bloco para 2*n inteiros. O resultado é armazenado em novo_vetor para não perder o ponteiro original em caso de falha.
  5. Se realloc falhar, liberamos vetor e saímos. Caso contrário, atualizamos vetor = novo_vetor.
  6. Preenchemos as novas posições de n a 2*n-1.
  7. Exibimos todos os elementos e liberamos a memória.

Por que funciona

realloc pode realocar o bloco em outro endereço, preservando os dados antigos. Ao usar uma variável temporária, evitamos vazamento caso a realocação falhe. O vetor resultante é contíguo e acessível pelos índices.

Erros comuns

  • Atribuir diretamente vetor = realloc(vetor, ...): se realloc falhar, perde-se a referência ao bloco original, causando vazamento.
    vetor = realloc(vetor, 2 * n * sizeof(int)); // perigoso
    
    Corrija usando um ponteiro temporário.
  • Esquecer de liberar o bloco original se realloc falhar: no código acima, free(vetor) é chamado antes de retornar.
  • Acessar índices além do novo tamanho: certifique-se de que os laços vão até 2*n.

Outra forma de resolver

Poderia alocar um novo vetor com malloc, copiar os dados antigos e liberar o antigo, mas realloc é mais simples e eficiente.

Saída esperada

Digite n: 5
0 1 2 3 4 5 6 7 8 9