Dangling Pointers
Use-after-free dangers.
Dangling Pointers is a free C Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is a Dangling Pointer
A dangling pointer points to memory that has already been freed or is otherwise no longer valid.
Using it leads to undefined behavior: crashes, corruption, or silent bugs.
#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;
}Use After Free
The most common cause is reading or writing through a pointer after free.
The block may have been reused for something else.
#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;
}Null After Free
Setting a pointer to NULL right after freeing turns an accidental use into a clear crash, or a harmless free(NULL).
#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;
}Returning a Local Address
Returning the address of a local (stack) variable creates a dangling pointer: the variable disappears when the function returns.
Use the heap or pass in a buffer instead.
#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;
}Multiple Pointers to One Block
If two pointers refer to the same block, freeing through one makes the other dangling.
Track ownership so only the owner frees.
#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;
}Dangling After realloc
When realloc moves a block, any old pointer to the previous location becomes dangling.
Only use the pointer realloc returned.
#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;
}Freeing in a Helper
If a helper frees a block, the caller's pointer is left dangling. Either null it after the call or design the helper to take a pointer-to-pointer.
#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;
}Why It Is Dangerous
Use-after-free is dangerous because the memory may now hold other data. Writes can corrupt unrelated state, and attackers can exploit it.
Scope-Based Danglers
A pointer to a block-scoped variable becomes invalid once the block ends. Keep pointers no longer than the lifetime of what they point to.
#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;
}Detecting Danglers
Tools like AddressSanitizer and Valgrind catch use-after-free at runtime, pointing to the exact line.
Build with sanitizers during development.
Safe Lifecycle Recap in Code
Allocate, use, free, and null. Following this consistently keeps pointers from dangling.
#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;
}Quick Check
Test your understanding of dangling pointers.
Recap
You learned about dangling pointers:
- They point to freed or out-of-scope memory; using them is undefined behavior.
- Avoid returning addresses of locals; never use a pointer after
freeor after realloc moves a block. - Set pointers to
NULLafter freeing and track ownership. - Use sanitizers and Valgrind to detect use-after-free.
Frequently asked questions
Is the “Dangling Pointers” lesson free?
Yes — the full text of “Dangling Pointers” is free to read here on the web, and the C Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C Academy course, upgrade to CoddyKit PRO.
What will I learn in “Dangling Pointers”?
Use-after-free dangers. You practise C Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start C Academy?
No prior experience is required. C Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Dangling Pointers” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this C Academy lesson?
Yes. Every C Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- malloc and free
- calloc and realloc
- Memory Leaks
- Dangling Pointers