Alocando com calloc()
Parte da seção Logic & Flow do Journey de C da Coddy — lição 36 de 63.
Embora malloc() seja a função mais comum para alocação dinâmica de memória, C fornece outra alternativa útil: calloc(). A função calloc(), que significa "contiguous allocation" (alocação contígua), oferece uma maneira conveniente de alocar memória para arrays com um benefício adicional importante.
Ao contrário do malloc(), que recebe um único argumento (total de bytes), o calloc() recebe dois argumentos: o número de elementos que você deseja alocar e o tamanho de cada elemento. Isso o torna particularmente intuitivo ao trabalhar com arrays. Por exemplo:
#include <stdlib.h>
// Aloca espaço para 5 inteiros usando calloc()
int *arr = (int*)calloc(5, sizeof(int));
// Isso é equivalente a: malloc(5 * sizeof(int))A principal vantagem do calloc() é que ele automaticamente inicializa toda a memória alocada com zero. Quando você usa malloc(), a memória alocada contém quaisquer valores aleatórios que estivessem armazenados anteriormente ali, mas o calloc() garante que cada byte seja definido como zero. Isso significa que todos os inteiros serão 0, todos os floats serão 0.0 e todos os ponteiros serão NULL.
Assim como o malloc(), o calloc() retorna um ponteiro para a memória alocada ou NULL se a alocação falhar, então você deve sempre verificar se houve falha na alocação e lembrar de usar free() na memória quando terminar de usá-la.
Desafio
FácilEscreva um programa em C que demonstre o uso de calloc() para alocação dinâmica de memória com inicialização automática em zero. Seu programa deve:
- Ler um número inteiro
sizedo usuário representando a quantidade de inteiros a serem alocados - Usar
calloc()para alocar dinamicamente memória para um array desizeinteiros - Verificar se a alocação de memória foi bem-sucedida - se falhar, imprima
Memory allocation failed!e encerre o programa - Se a alocação for bem-sucedida, imprima
Memory allocated and initialized to zero! - Imprima todos os valores iniciais no array para demonstrar que são zero, no formato:
Initial values: [valor1] [valor2] [valor3] ... - Leia
sizevalores inteiros do usuário e armazene-os no array alocado - Imprima todos os valores atualizados no formato:
Updated values: [valor1] [valor2] [valor3] ... - Calcule e imprima a soma de todos os valores no formato:
Sum: [valor] - Use
free()para desalocar a memória - Imprima
Memory freed!para confirmar a limpeza
Lembre-se de incluir o cabeçalho <stdlib.h> para usar calloc() e free(). Este desafio demonstra a principal vantagem de calloc() sobre malloc(): a inicialização automática de toda a memória alocada para zero.
Por exemplo, se a entrada for:
3
10 20 30Sua saída deve ser:
Memory allocated and initialized to zero!
Initial values: 0 0 0
Updated values: 10 20 30
Sum: 60
Memory freed!Este desafio destaca como calloc() fornece um estado inicial limpo e previsível para seus arrays alocados dinamicamente, eliminando os valores de lixo imprevisíveis que malloc() pode deixar para trás.
Folha de consulta
A função calloc() fornece alocação dinâmica de memória com inicialização automática em zero.
Sintaxe:
void* calloc(size_t num_elements, size_t element_size);Principais diferenças em relação ao malloc():
- Recebe dois argumentos: número de elementos e tamanho de cada elemento
- Inicializa automaticamente toda a memória alocada para zero
- Mais intuitivo para alocação de arrays
Exemplo de uso:
#include <stdlib.h>
// Aloca espaço para 5 inteiros usando calloc()
int *arr = (int*)calloc(5, sizeof(int));
// Isso é equivalente a: malloc(5 * sizeof(int))
// Mas todos os valores são garantidos como 0Assim como o malloc(), o calloc() retorna um ponteiro para a memória alocada ou NULL se a alocação falhar. Sempre verifique se houve falha na alocação e use free() para desalocar a memória quando terminar.
Experimente você mesmo
#include <stdio.h>
#include <stdlib.h>
int main() {
int size;
// Leia o tamanho do array
scanf("%d", &size);
// TODO: Escreva seu código abaixo
// Use calloc() para alocar memória para o array
// Verifique se a alocação foi bem-sucedida
// Imprima os valores iniciais (devem ser zero)
// Leia e armazene os valores de entrada
// Imprima os valores atualizados
// Calcule e imprima a soma
// Libere a memória alocada
return 0;
}Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Logic & Flow
1Fundamentos de Ponteiros
O que é um Ponteiro?Declarando PonteirosO Operador de Endereço (&)O Operador de Desreferência (*)Ponteiros NULLRecapitulação: Fundamentos de Ponteiros4Projeto: Utilitário de Texto Simples
Visão Geral do ProjetoContando Caracteres2Ponteiros e Arrays
Nomes de Arrays como PonteirosElementos de Array - PonteirosAritmética de PonteirosComparando PonteirosRecapitulação: Percorrendo Arrays com Ponteiros5Ponteiros e Funções
Passagem por ValorPassando Ponteiros para FunçõesModificando Variáveis via PonteirosUm Exemplo Clássico: SwapPassando Arrays para FunçõesRecapitulação: Ponteiros como Argumentos3Arrays de Caracteres e Strings
Strings como Arrays de charO Terminador NuloEntrada de Strings com scanfUsando strlen()Usando strcpy()Usando strcat()Usando strcmp()Recapitulação: Funções Básicas de Strings6Gerenciamento de Memória
Memória Stack vs. HeapAlocação Dinâmica - malloc()Usando sizeof() para AlocaçãoVerificando Falhas de AlocaçãoLiberando Memória com free()Alocando com calloc()Recapitulação: Array Dinâmico9Projeto: Cadastro Simples de Contatos
Projeto: Definir a Struct de ContatoFunção para Criar um Contato