O que você precisa saber sobre vetores em C
Vetores em C são simplesmente arrays unidimensionais. A sintaxe é direta: tipo nome[tamanho]; por exemplo, int notas[30]; cria um vetor de 30 posições inteiras. O índice começa em zero. Posições válidas vão de 0 a tamanho - 1. Acessar fora desse intervalo não gera erro de compilação, mas o programa pode travar ou corromper memória em tempo de execução. Isso acontece constantemente com iniciantes e até com desenvolvedores experientes que estão apressados.
vetor linguagem c
A maneira padrão de declarar um vetor fixo é usando a sintaxe de colchetes. Mas o que a maioria das pessoas procura na prática é um vetor dinâmico, que cresce conforme os dados chegam. Isso exige malloc e realloc. Veja um exemplo mínimo: int *vetor = NULL;
int capacidade = 0;
int tamanho = 0;
// para adicionar um elemento:
if (tamanho >= capacidade) {
capacidade = capacidade == 0 ? 1 : capacidade * 2;
vetor = realloc(vetor, capacidade * sizeof(int));
}
vetor[tamanho++] = novo_valor; Esse padrão de dobrar a capacidade é o mais comum. Existem outras estratégias, como crescer linearmente, mas a exponencial é a que geralmente se sai melhor em benchmarks simples. O problema real é que realloc pode falhar e retornar NULL. Se você passar o ponteiro original direto para realloc sem verificar, perde a referência e vaza memória. A solução segura é usar um temporário:
int *temp = realloc(vetor, nova_capacidade * sizeof(int));
if (temp == NULL) { /* tratar erro */ }
vetor = temp; Um detalhe que muita gente esquece: quando o vetor está vazio e capacidade é zero, a primeira alocação com realloc funciona em C99, mas o código fica mais legível se você tratar o caso especial explicitamente. Eu configurei isso como capacidade inicial igual a 1 por esse motivo.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Lembre-se de liberar a memória com free() quando terminar. Esquecer o free é um dos vazamentos mais banais que eu já vi em code review. Programas pequenos não sofrem tanto, mas em serviços que rodam semanas sem reiniciar, cada byte esquecido acumula e o processo eventualmente consome toda a memória disponível. Outro ponto prático: vetores em C não carregam informações de tamanho junto com os dados. Você precisa manter uma variável separada para o tamanho atual e outra para a capacidade. Isso é diferente de linguagens como Python ou Go, onde o tamanho é parte da estrutura. Em C, se você passar apenas o ponteiro para uma função, essa função não sabe quantos elementos existem. O conventional workaround é passar o tamanho como argumento adicional. Funções que manipulam vetores costumam seguir essa assinatura:
void processar(int *dados, int tamanho); Sobre performance, vetores em C são extremamente rápidos para acesso aleatório porque a posição de qualquer elemento é calculada como base + índice * tamanho_do_tipo. Isso é uma única operação aritmética. Comparado a listas encadeadas, o acesso é significativamente mais rápido devido à localidade de cache. O lado negativo é que inserções e remoções no meio do vetor exigem deslocar todos os elementos seguintes, o que é O(n). Se você faz muitas inserções em posições arbitrárias, considere uma lista encadeada ou outra estrutura.
Um bug que eu encontrei recentemente envolveu realloc em um loop onde o vetor crescia a cada iteração. O código parecia correto, mas a variável de capacidade não estava sendo atualizada corretamente dentro de uma função helper. O vetor realocava com tamanho insuficiente repetidamente, causando sobrescrita de memória adjacente. A correção foi garantir que a capacidade fosse passada por referência ou retornada pela função. Isso deveria ser óbvio, mas passa despercebido porque o comportamento é indeterminado e o crash pode acontecer segundos depois do ponto de erro real. Se você quer algo pronto para uso sem implementar do zero, a biblioteca vec do projetistas do WAVM é uma opção sólida para C, assim como a libdv do Daniel Holden. Ambas oferecem interface similar a std::vector do C++ e tratam realloc, tamanho e capacidade de forma encapsulada. Usar uma biblioteca dessas economiza tempo e reduz bugs comuns de gestão manual de memória.
Para declaração estática com tamanho conhecido em tempo de compilação, vetores na pilha funcionam bem e são mais simples. O limite é que o tamanho deve ser constante ou pelo menos conhecido antes da execução, e memórias muito grandes na pilha podem estourar o stack. Nesse caso, alocação dinâmica no heap é o caminho. O essencial é entender que vetor em C é uma ferramenta bruta. Ela entrega performance e controle, mas cobra preciseza em troca. Cada acesso, cada realloc, cada free precisa ser pensado. Quando você domina o padrão, o desenvolvimento fica rápido e direto. Quando não domina, problemas de memória aparecem de forma intermitente e difícil de reproduzir.