Ponteiros pendentes
Perigos do uso após liberar.
Ponteiros pendentes é uma aula grátis de C Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C Academy inclui 4 aulas no total.
O que é um ponteiro pendente
Um ponteiro pendente aponta para uma região de memória que já foi liberada ou que, de alguma outra forma, deixou de ser válida.
Usá-lo causa comportamento indefinido: falhas, corrupção ou erros silenciosos.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = malloc(sizeof(int));
*p = 5;
printf("%d\n", *p);
free(p);
p = NULL;
return 0;
}Uso após liberação
A causa mais comum é ler ou escrever por meio de um ponteiro depois de free.
O bloco pode ter sido reutilizado para outra finalidade.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = malloc(sizeof(int));
*p = 42;
free(p);
/* Reading *p here would be use-after-free. */
p = NULL;
printf("avoided use-after-free\n");
return 0;
}Nulo após a liberação
Definir um ponteiro como NULL logo após liberá-lo transforma um uso acidental em uma falha evidente ou em um free(NULL) inofensivo.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *buf = malloc(10);
buf[0] = 'A';
free(buf);
buf = NULL;
if (buf == NULL) printf("buf is safely null\n");
return 0;
}Retornando um endereço local
Retornar o endereço de uma variável local (da pilha) cria um ponteiro pendente: a variável desaparece quando a função retorna.
Use a memória de heap ou passe um buffer como alternativa.
#include <stdio.h>
#include <stdlib.h>
int *make_value(int v) {
int *p = malloc(sizeof(int));
*p = v;
return p;
}
int main(void) {
int *p = make_value(99);
printf("%d\n", *p);
free(p);
return 0;
}Vários ponteiros para um bloco
Se dois ponteiros se referem ao mesmo bloco, liberá-lo por meio de um deles deixa o outro pendente.
Acompanhe a propriedade para que somente o proprietário faça a liberação.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *a = malloc(sizeof(int));
*a = 7;
int *b = a;
printf("%d\n", *b);
free(a);
a = NULL;
b = NULL;
printf("both nulled\n");
return 0;
}Pendente após realloc
Quando realloc move um bloco, qualquer ponteiro antigo para a localização anterior se torna pendente.
Use somente o ponteiro retornado por realloc.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *a = malloc(sizeof(int));
a[0] = 1;
int *b = realloc(a, 50 * sizeof(int));
/* a may now be dangling; use only b. */
b[0] = 2;
printf("%d\n", b[0]);
free(b);
return 0;
}Liberando em uma função auxiliar
Se uma função auxiliar libera um bloco, o ponteiro do chamador fica pendente. Anule-o após a chamada ou projete a função auxiliar para receber um ponteiro para ponteiro.
#include <stdio.h>
#include <stdlib.h>
void destroy(int **p) {
free(*p);
*p = NULL;
}
int main(void) {
int *p = malloc(sizeof(int));
*p = 5;
destroy(&p);
printf("p is %s\n", p == NULL ? "null" : "set");
return 0;
}Por que isso é perigoso
O uso após a liberação é perigoso porque a memória pode agora conter outros dados. As escritas podem corromper estados não relacionados, e invasores podem explorá-lo.
Ponteiros pendentes por escopo
Um ponteiro para uma variável cujo escopo é o bloco se torna inválido quando o bloco termina. Mantenha os ponteiros somente durante o tempo de vida daquilo para que apontam.
#include <stdio.h>
int main(void) {
int *p;
{
int x = 10;
p = &x;
printf("in scope: %d\n", *p);
}
/* p now dangles; do not dereference it here. */
printf("block ended\n");
return 0;
}Detectando ponteiros pendentes
Ferramentas como AddressSanitizer e Valgrind detectam o uso após a liberação durante a execução, indicando a linha exata.
Compile com sanitizadores durante o desenvolvimento.
Recapitulação do ciclo de vida seguro no código
Alocar, usar, liberar e anular. Seguir essa sequência de forma consistente impede que os ponteiros fiquem pendentes.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = malloc(sizeof(int));
if (!p) return 1;
*p = 123;
printf("%d\n", *p);
free(p);
p = NULL;
return 0;
}Verificação rápida
Teste sua compreensão sobre ponteiros pendentes.
Recapitulação
Você aprendeu sobre ponteiros pendentes:
- Eles apontam para memória liberada ou fora do escopo; usá-los é um comportamento indefinido.
- Evite retornar endereços de variáveis locais; nunca use um ponteiro depois de
freeou depois que realloc mover um bloco. - Defina os ponteiros como
NULLapós liberá-los e acompanhe a propriedade. - Use sanitizadores e Valgrind para detectar o uso após a liberação.
Perguntas Frequentes
A aula “Ponteiros pendentes” é grátis?
Sim — o texto completo de “Ponteiros pendentes” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C Academy, atualize para CoddyKit PRO. O curso de C Academy inclui 4 aulas no total.
O que vou aprender em “Ponteiros pendentes”?
Perigos do uso após liberar. Você pratica C Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar C Academy?
Nenhuma experiência prévia é necessária. C Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Ponteiros pendentes”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de C Academy?
Sim. Cada aula de C Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- malloc e free
- calloc e realloc
- Vazamentos de memória
- Ponteiros pendentes