← Back to C Course | Chapter 9: Memory Management | Lesson 6 of 8

C free()

free gives borrowed memory back to the computer, like returning a library book. Using it twice or after returning causes problems.
Syntax
c
free(pointer_name);
pointer_name = NULL;  // avoid a dangling pointer

Why free() memory?

This manual responsibility is the core tradeoff of C's memory model -- there's no garbage collector watching for unused memory, so every successful malloc(), calloc(), or realloc() call needs a matching free() somewhere in your program's logic.

Example: Why free() memory?

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Program execution starts in main()
int main() {
	// Allocate memory on the heap
	int *ptr = malloc(sizeof(int));
	*ptr = 5;
	// Print formatted text to the screen
	printf("%d", *ptr);
	// Release the heap memory so it can be reused
	free(ptr);
	// Return 0 to signal that the program finished successfully
	return 0;
}

How to use free()

free() doesn't erase the pointer variable itself, only the memory it pointed to -- so the pointer still holds the same (now-invalid) address afterward, which is why setting it to NULL immediately after freeing is considered good practice.

Example: How to use free()

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Program execution starts in main()
int main() {
	// Allocate memory on the heap
	int *ptr = malloc(sizeof(int));
	*ptr = 10;
	// Release the heap memory so it can be reused
	free(ptr);
	ptr = NULL;
	// Print formatted text to the screen
	printf("%d", ptr == NULL);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Double free error

This corruption happens because free() may reuse that same memory region internally for its own bookkeeping after the first free() call, so a second free() on the same address can corrupt the allocator's internal data structures.

Example: Double free error

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Program execution starts in main()
int main() {
	// Allocate memory on the heap
	int *ptr = malloc(sizeof(int));
	// Release the heap memory so it can be reused
	free(ptr);
	ptr = NULL;
	// Print formatted text to the screen
	printf("%d", ptr == NULL);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Dangling pointers after free()

This is one of the most notorious classes of C bugs (a use-after-free), since the pointer looks perfectly valid and dereferencing it might even appear to work by coincidence, until it silently corrupts unrelated data.

Example: Dangling pointers after free()

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Program execution starts in main()
int main() {
	// Allocate memory on the heap
	int *ptr = malloc(sizeof(int));
	*ptr = 5;
	// Release the heap memory so it can be reused
	free(ptr);
	ptr = NULL;
	// Print formatted text to the screen
	printf("%d", ptr == NULL);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Freeing dynamic structures

This ordering matters because once you free the outer structure, you lose any way to reach the inner pointers it contained -- freeing must always happen from the 'inside out,' starting with the most deeply nested allocations first.

Example: Freeing dynamic structures

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Define a structure type named Node
struct Node { int value; struct Node *next; };
// Program execution starts in main()
int main() {
	// Allocate memory on the heap
	struct Node *inner = malloc(sizeof(struct Node));
	// Allocate memory on the heap
	struct Node *outer = malloc(sizeof(struct Node));
	outer->next = inner;
	// Release the heap memory so it can be reused
	free(inner);
	// Release the heap memory so it can be reused
	free(outer);
	printf("Freed inside-out");
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Calling free twice on the same pointer, which is undefined behavior.
  2. Using a pointer after freeing it (dangling pointer).
  3. Calling free on memory that was not allocated with malloc.
🔒

Chapter Quiz — Complete all 8 topics to unlock

0/8 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.