Desafio C
Vetor dinâmico sem vazamentos
Enunciado
Implemente um programa que leia uma sequência de números inteiros positivos do usuário (terminada por 0) e armazene-os em um vetor dinâmico que cresce conforme a necessidade. A cada leitura, se o vetor estiver cheio, dobre sua capacidade usando realloc. Ao final, exiba todos os números na ordem em que foram digitados e libere toda a memória. Certifique-se de que não haja vazamentos.
Requisitos
- Usar
mallocpara a alocação inicial. - Usar
reallocpara dobrar a capacidade quando necessário. - Ler números até que 0 seja digitado (0 não deve ser armazenado).
- Exibir os números na ordem de entrada.
- Liberar a memória com
free. - Verificar erros de alocação.
Código inicial
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int capacidade = 4;
int tamanho = 0;
int *vetor = malloc(capacidade * sizeof(int));
if (vetor == NULL) {
printf("Erro: malloc falhou\n");
return 1;
}
int num;
printf("Digite números (0 para sair): ");
while (scanf("%d", &num) == 1 && num != 0) {
// Seu código aqui
}
// Exibir e liberar
return 0;
}
Saída esperada
Digite números (0 para sair): 10 20 30 40 50 0
10 20 30 40 50
Ver dica
Quando tamanho == capacidade, use realloc para dobrar a capacidade. Lembre-se de atualizar o ponteiro corretamente e verificar falhas.
Mostrar solução
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int capacidade = 4;
int tamanho = 0;
int *vetor = malloc(capacidade * sizeof(int));
if (vetor == NULL) {
printf("Erro: malloc falhou\n");
return 1;
}
int num;
printf("Digite números (0 para sair): ");
while (scanf("%d", &num) == 1 && num != 0) {
// Se o vetor estiver cheio, dobra a capacidade
if (tamanho == capacidade) {
capacidade *= 2;
int *novo_vetor = realloc(vetor, capacidade * sizeof(int));
if (novo_vetor == NULL) {
printf("Erro: realloc falhou\n");
free(vetor);
return 1;
}
vetor = novo_vetor;
}
vetor[tamanho++] = num;
}
// Exibe os números armazenados
for (int i = 0; i < tamanho; i++) {
printf("%d ", vetor[i]);
}
printf("\n");
// Libera a memória
free(vetor);
return 0;
}
Passo a passo
- Inicializamos
capacidade = 4etamanho = 0. Alocamos espaço para 4 inteiros commalloc. - Verificamos se
mallocretornouNULL. - Iniciamos um laço que lê números com
scanfaté que o valor seja 0 ou a leitura falhe. - Dentro do laço, se
tamanho == capacidade, dobramoscapacidadee chamamosreallocpara expandir o bloco. Usamos um ponteiro temporárionovo_vetorpara não perdervetorem caso de falha. - Se
reallocfalhar, liberamosvetore encerramos. Caso contrário, atualizamosvetor = novo_vetor. - Armazenamos o número lido em
vetor[tamanho]e incrementamostamanho. - Após o laço, exibimos todos os elementos armazenados.
- Liberamos a memória com
free(vetor).
Por que funciona
O vetor cresce dinamicamente conforme a necessidade, evitando desperdício e permitindo armazenar uma quantidade arbitrária de números. O uso de realloc com verificação de erro garante que a memória seja gerenciada corretamente. A liberação final evita vazamentos.
Erros comuns
- Não verificar o retorno de
realloc: se falhar, o ponteiro original é perdido, causando vazamento.
Corrija usando um ponteiro temporário.vetor = realloc(vetor, capacidade * sizeof(int)); // perigoso - Esquecer de dobrar a capacidade antes de realocar: isso pode causar realocação desnecessária ou estouro.
- Não liberar a memória no final: o programa termina, mas o vazamento é uma má prática.
- Acessar
vetorapósfree: certifique-se de não usar o ponteiro depois de liberar.
Outra forma de resolver
Poderia usar uma lista encadeada, que não requer realocação, mas tem maior overhead de memória e pior localidade de cache. O vetor dinâmico é mais eficiente para acesso aleatório.
Saída esperada
Digite números (0 para sair): 10 20 30 40 50 0
10 20 30 40 50