🚀 Capítulo 13: Alocação Dinâmica de Memória (malloc, calloc, realloc e free) em C
🎯 Objetivos da Aula
Ao final desta aula, você será capaz de:
- Compreender a diferença entre a memória Stack (estática) e a memória Heap (dinâmica).
- Requisitar blocos de memória em tempo de execução usando
malloc()ecalloc(). - Redimensionar vetores alocados na Heap utilizando a função
realloc(). - Liberar a memória alocada dinamicamente com
free()evitando vazamentos de memória (Memory Leaks).
🧠 1. Memória Stack vs Memória Heap
Em C, a memória RAM alocada para uma aplicação divide-se em duas regiões principais de gerenciamento de dados:
flowchart TD subgraph RAM ["Organização da Memória RAM em C"] Stack["Memória STACK (Estática)\n- Tamanho fixo em tempo de compilação\n- Gerenciada automaticamente pelo sistema\n- Ex.: int x; float notas[10];"] Heap["Memória HEAP (Dinâmica)\n- Tamanho flexível em tempo de execução\n- Gerenciada MANUALMENTE pelo programador\n- Requer malloc() e free()"] end
Funções da Biblioteca <stdlib.h> para Gerenciamento da Heap:
malloc(tamanho_em_bytes): Aloca um bloco contíguo de bytes no Heap. Retorna o ponteiro para o primeiro byte ouNULLem caso de falha. O conteúdo inicial é lixo de memória.calloc(qtd, tamanho_unidade): Aloca memória paraqtdelementos e inicializa todos os bits com zero (0).realloc(ptr, novo_tamanho): Redimensiona um bloco previamente alocado, preservando o conteúdo anterior.free(ptr): Devolve o bloco de memória apontado porptrde volta ao Sistema Operacional.
💻 2. Prática Guiada: Vetor Dinâmico de Notas em C
Vamos escrever o programa alocacao_dinamica.c para alocar dinamicamente um vetor do tamanho exato informado pelo usuário:
#include <stdio.h>
#include <stdlib.h> // Obrigatorio para malloc, calloc, free
int main() {
int qtdAlunos = 0;
float *vetorNotas = NULL;
printf("Digite a quantidade de alunos da turma: ");
scanf("%d", &qtdAlunos);
// 1. Alocacao Dinamica na Heap usando malloc
vetorNotas = (float*) malloc(qtdAlunos * sizeof(float));
// 2. Validação obrigatória da alocação
if (vetorNotas == NULL) {
printf(">> ERRO CRITICO: Memoria insuficiente no Heap!\n");
return 1; // Encerra com código de erro
}
printf("\n>> Memoria alocada com sucesso no endereco: %p\n", (void*)vetorNotas);
// 3. Leitura dos dados no vetor dinâmico
for (int i = 0; i < qtdAlunos; i++) {
printf("Digite a nota do Aluno %d: ", i + 1);
scanf("%f", &vetorNotas[i]);
}
// 4. Processamento da média
float soma = 0.0f;
for (int i = 0; i < qtdAlunos; i++) {
soma += vetorNotas[i];
}
float mediaTurma = soma / qtdAlunos;
printf("\n=========================================\n");
printf(" Media da Turma (%d alunos): %.2f\n", qtdAlunos, mediaTurma);
printf("=========================================\n");
// 5. LIBERAÇÃO OBRIGATÓRIA DA MEMÓRIA ALOCADA!
free(vetorNotas);
vetorNotas = NULL; // Evita ponteiro solto (Dangling Pointer)
printf(">> Memoria liberada com sucesso.\n");
return 0;
}⚔️ 3. Desafios Práticos (Exercícios 30/50/20)
🥉 Nível Bronze (Fixação)
- O que é um vazamento de memória (Memory Leak) e por que ele pode travar um servidor após longo tempo de execução?
- Qual a diferença de comportamento entre
malloc()ecalloc()ao inicializar os bytes alocados?
🥈 Nível Prata (Aplicação)
- Escreva um programa em C que utilize
malloc()para alocar dinamicamente um vetor deintde tamanho 5. Preencha com números inteiros e depois utilizerealloc()para expandir o tamanho do vetor para 10 elementos sem perder os valores anteriores.
🥇 Nível Ouro (Desafio)
- Escreva uma função em C
struct Aluno* criarAlunoDinamico(char *nome, int idade)que aloque dinamicamente umastruct Alunono Heap, preencha seus campos e retorne o ponteiro para amain(), onde o aluno será impresso e liberado comfree().
💡 Gabaritos Sanfonados de Resposta
💡 Ver Gabarito do Nível Bronze
- Ocorre quando a memória é alocada dinamicamente com
malloc/callocmas o programador esquece de usarfree(). A memória permanece inacessível e ocupada, podendo esgotar a RAM do servidor (Out of Memory). - O
malloc()apenas reserva os bytes sem limpar o conteúdo (contém “lixo” de memória). Ocalloc()aloca e zera explicitamente todos os bytes (0).
💡 Ver Gabarito do Nível Prata & Ouro (Código C)
#include <stdio.h>
#include <stdlib.h>
int main() {
int *vetor = (int*) malloc(5 * sizeof(int));
if (vetor == NULL) return 1;
for (int i = 0; i < 5; i++) vetor[i] = (i + 1) * 10;
// Expandindo para 10 elementos com realloc
vetor = (int*) realloc(vetor, 10 * sizeof(int));
for (int i = 5; i < 10; i++) vetor[i] = (i + 1) * 10;
printf("Vetor Expandido:\n");
for (int i = 0; i < 10; i++) printf("%d ", vetor[i]);
printf("\n");
free(vetor);
return 0;
}📚 Referências Teóricas Oficiais
- KERNIGHAN, Brian W.; RITCHIE, Dennis M.. A Linguagem de Programação C. 2ª Edição. Campus, 1989. Cap. 7 (Alocação Dinâmica).
- STALLINGS, William. Arquitetura e Organização de Computadores — Gerenciamento de Memória. 10ª Edição. Pearson, 2017.
⬅️ Capítulo Anterior (Passagem por Referência) | Voltar ao Sumário | Próximo Capítulo (Manipulação de Arquivos) ➡️