Memory Management
How memory is allocated and freed
Introduction
In this lesson, you'll learn about memory management in C#. Coming from C, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In C, you're familiar with how memory is allocated and freed.
C# has its own approach to how memory is allocated and freed, which we'll explore step by step.
The C# Way
Let's see how C# handles this concept. Here's a typical example:
// C# has automatic garbage collection — no free()!
// Reference types — heap, GC managed
var list = new List<int> { 1, 2, 3 };
var str = "hello"; // immutable string object
// Value types — stack (like C local vars)
int x = 42;
var pt = new System.Drawing.Point(1, 2); // struct
// IDisposable — for unmanaged resources (files, DB)
using (var file = System.IO.File.OpenRead("data.txt")) {
// file is closed/freed automatically at end of block
}
// Modern C# — using declaration
using var reader = new System.IO.StreamReader("data.txt");
// reader disposed at end of scopeComparing to C
Here's how you might have written similar code in C:
#include <stdlib.h>
#include <string.h>
/* Stack allocation */
int x = 42;
/* Heap — must free */
int *arr = malloc(10 * sizeof(int));
char *str = strdup("hello");
/* Use */
arr[0] = 1;
/* Free or leak! */
free(arr);
free(str);
/* Common pitfalls */
arr = NULL; /* avoid dangling pointer */
/* double-free: UB */
/* use-after-free: UB */You may be used to different syntax or behavior.
C# GC frees heap objects automatically; no malloc/free needed
You may be used to different syntax or behavior.
C# has no dangling pointers or double-free bugs
You may be used to different syntax or behavior.
IDisposable + using replaces explicit fclose/resource cleanup
You may be used to different syntax or behavior.
Value types (struct) are stack-allocated like C local variables
Step-by-Step Breakdown
1. No malloc/free
The .NET GC tracks object references and frees memory when objects are no longer reachable. No manual memory management required.
int *arr = malloc(10 * sizeof(int));
free(arr);var arr = new int[10];
// GC frees when arr goes out of scope2. IDisposable for Resources
For unmanaged resources like file handles or database connections, C# uses the IDisposable pattern with 'using' statements.
FILE *f = fopen("file.txt", "r");
// ... use f ...
fclose(f);using var f = File.OpenRead("file.txt");
// auto-closed at end of block3. Value vs Reference Types
C# structs are value types (copied on assignment like C variables). Classes are reference types (shared like C pointers).
Common Mistakes
When coming from C, developers often make these mistakes:
- C# GC frees heap objects automatically; no malloc/free needed
- C# has no dangling pointers or double-free bugs
- IDisposable + using replaces explicit fclose/resource cleanup
Key Takeaways
- GC replaces malloc/free — no memory leaks or dangling pointers
- using statement handles unmanaged resource cleanup
- struct = value type (stack); class = reference type (heap GC)
- No undefined behavior from memory bugs