How memory in c works
π Memory in C Programming
C programming provides low-level access to memory, which makes it powerful but also risky if not used carefully. Understanding memory management and pointers is crucial for efficient and bug-free C programs.
1οΈβ£ Memory Layout of a C Program
When a C program runs, memory is divided into different segments:
- Text Segment (Code Segment)
Stores compiled machine instructions.
Usually read-only (prevents modifying instructions at runtime).
- Data Segment
Stores global and static variables.
Divided into:
Initialized Data Segment β variables with defined values.
Uninitialized Data Segment (BSS) β variables initialized to zero or left uninitialized.
- Heap
Used for dynamic memory allocation (malloc, calloc, realloc, free).
Grows upwards (towards higher memory addresses).
- Stack
Used for function calls, local variables, and return addresses.
Grows downwards (towards lower memory addresses).
π Example:
High Address +-------------------+ | Command-line | | Arguments | +-------------------+ | Stack | <--- grows downward +-------------------+ | Heap | <--- grows upward +-------------------+ | Uninitialized | | Data (BSS) | +-------------------+ | Initialized | | Data | +-------------------+ | Code | +-------------------+ Low Address
2οΈβ£ Pointers in C
A pointer is a variable that stores the memory address of another variable.
Syntax:
int a = 10; int *p = &a; // p stores address of a
Important Operators:
& β Address-of operator (gets memory address).
- β Dereference operator (access value at the address).
π Example:
#include <stdio.h> int main() { int x = 42; int *ptr = &x;
printf("Value of x: %d\n", x);
printf("Address of x: %p\n", &x);
printf("Value stored in ptr: %p\n", ptr);
printf("Value pointed by ptr: %d\n", *ptr);
return 0;
}
3οΈβ£ Types of Pointers
- Null Pointer β Points to nothing.
int *p = NULL;
- Void Pointer β Generic pointer (can store address of any type).
void *ptr;
- Dangling Pointer β Points to freed or invalid memory.
int *p; { int x = 10; p = &x; } // x goes out of scope β p becomes dangling
- Wild Pointer β Uninitialized pointer (random address).
int *p; // not initialized
- Function Pointer β Points to a function.
int add(int a, int b) { return a+b; } int (*fp)(int, int) = &add;
4οΈβ£ Pointer Arithmetic
Pointers can be incremented/decremented to move across memory addresses.
Example:
int arr[3] = {10, 20, 30}; int *p = arr;
printf("%d\n", *p); // 10 p++; printf("%d\n", *p); // 20
π Note: Increment depends on data type size.
int *p β moves by 4 bytes (on 32-bit system).
char *p β moves by 1 byte.
5οΈβ£ Dynamic Memory Allocation
C provides library functions (stdlib.h) for heap memory management:
- malloc() β Allocates uninitialized memory.
int p = (int) malloc(5 * sizeof(int));
- calloc() β Allocates zero-initialized memory.
int p = (int) calloc(5, sizeof(int));
- realloc() β Resizes previously allocated memory.
p = (int*) realloc(p, 10 * sizeof(int));
- free() β Frees allocated memory.
free(p);
6οΈβ£ Memory Issues in C
-
Memory Leak β Forgetting to free memory.
-
Segmentation Fault β Accessing invalid memory.
-
Dangling Pointers β Using freed/unavailable memory.
-
Buffer Overflow β Writing outside allocated memory.
7οΈβ£ Example Program (Dynamic Array with Pointers)
#include <stdio.h> #include <stdlib.h>
int main() { int n, i; printf("Enter number of elements: "); scanf("%d", &n);
int *arr = (int*) malloc(n * sizeof(int));
if(arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
printf("Enter elements:\n");
for(i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
printf("You entered:\n");
for(i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
free(arr); // release memory
return 0;
}
8οΈβ£ Key Takeaways
Memory in C is divided into Code, Data, Heap, and Stack.
Pointers are used to directly access memory addresses.
Proper use of malloc/calloc/realloc/free is essential.
Always watch out for dangling pointers and memory leaks.