Teste seu entendimento sobre malloc/free, ponteiros soltos, vazamentos de memória e calloc.
int *p = (int *)malloc(sizeof(int) * 3); p[0] = 10; p[1] = 20; p[2] = 30; printf("%d\n", p[1]); free(p);
malloc(sizeof(int)*3) aloca espaço para 3 ints no heap. p[1] é o segundo elemento → 20.int *p = (int *)malloc(sizeof(int)); *p = 42; free(p); printf("%d\n", *p);
free (um ponteiro solto) é comportamento indefinido.p = NULL; logo depois do free.void func(void) { int *p = (int *)malloc(sizeof(int) * 100); *p = 42; // esqueceu de free(p) }
free, o ponteiro é perdido e a memória alocada nunca mais pode ser devolvida ao heap.int *a = (int *)calloc(5, sizeof(int)); printf("%d %d %d\n", a[0], a[2], a[4]); free(a);
malloc, o calloc inicializa com zero a memória alocada.calloc sempre que quiser memória inicializada com zero.int *p = (int *)malloc(sizeof(int)); *p = 10; free(p); free(p); // libera o mesmo ponteiro novamente
free num ponteiro já liberado é comportamento indefinido (double free).
NULL logo depois de liberar. free(NULL) é seguro — o padrão garante que é uma operação sem efeito.
// Ponteiro tem 8 bytes, int tem 4 bytes int *p = (int *)malloc(sizeof(int) * 10); printf("%lu\n", sizeof(p));
p é uma variável ponteiro, então sizeof(p) retorna o tamanho do próprio ponteiro.
sizeof não consegue dizer o tamanho de uma região alocada com mallocmalloc não devolve essa informação.
int *p = (int *)malloc(sizeof(int) * 3); int *q = p; // backup de p p = (int *)realloc(p, sizeof(int) * 100); // O que acontece se usarmos q agora?
q depois do realloc está correta?realloc não conseguir estender a região existente no mesmo lugar, ele copia os dados para um novo endereço e libera o antigo.
q ainda é válidoq foi liberado, então q está inválido (ponteiro solto)realloc, você nunca deve usar o ponteiro original — apenas o novo que o realloc retornou. Além disso, se o realloc falhar ele retorna NULL sem liberar o original, então o padrão seguro é tmp = realloc(p, ...); if (tmp) p = tmp;.
int *p = (int *)malloc(sizeof(int) * 1000000000); *p = 42; // sem verificação de NULL
*p causa um segmentation fault*pmalloc falha, ele retorna NULL.
*p sem verificar se é NULL trava o programaif (p == NULL) { /* tratar erro */ }int *p = malloc(...);
if (p == NULL) {
fprintf(stderr, "Out of memory\n");
return 1;
}
int *p = NULL; free(p); // libera um ponteiro NULL printf("OK\n");
free(NULL) é uma operação sem efeito.
free sem verificar NULL, o que simplifica o código de tratamento de errosif (p != NULL) free(p);p = NULL; logo depois de cada free.