Understanding Memory Management and the new Operator in C++
Memory Layout in C++ Programs
During execution, a C++ program organizes memory into four primary regions:
- Code Segment: Stores compiled binary instructions, managed by the OS
- Global/Static Segment: Contains global variables, static variables, and constants
- Stack: Automatically managed memory for function parameters and local variables
- Heap: Dynamically allocated memory controlled by the programmer
Pre-Runtime Memory Areas
Before program execution begins, two memory regions are established:
Code Segment Characteristics
- Contains CPU-executable machine instructions
- Shared across processes to optimize memory usage
- Marked read-only to prevent accidental modification
Global/Static Segment Contents
- Stores global and static variables
- Includes constant data (string literals, const globals)
- Memory is released by the OS upon program termination
Memory Address Demonstration
// Global variables
int global_x = 20;
int global_y = 20;
// Global constants
const int const_global_x = 20;
const int const_global_y = 20;
int main() {
// Local variables
int local_x = 20;
int local_y = 20;
// Display addresses
cout << "Local x: " << (long)&local_x << endl;
cout << "Local y: " << (long)&local_y << endl;
// Static variables
static int static_x = 20;
static int static_y = 20;
cout << "Static x: " << (long)&static_x << endl;
cout << "Static y: " << (long)&static_y << endl;
// Constants
cout << "String literal: " << (long)&"sample text" << endl;
cout << "Global const x: " << (long)&const_global_x << endl;
const int const_local_x = 20;
cout << "Local const x: " << (long)&const_local_x << endl;
return 0;
}
Runtime Memory Areas
Stack Memory Behavior
- Automatically managed by the compiler
- Stores function parameters and local variables
- Warning: Never return pointers to stack-allocated data
int* badFunction() {
int stack_var = 30;
return &stack_var; // Dangerous!
}
Heap Memory Operations
- Requires explicit allocation/deallocation
- Primary allocation method:
newoperator
int* safeFunction() {
int* heap_var = new int(30);
return heap_var; // Valid
}
Dynamic Memory Allcoation with new
The new operator allocates heap memory and returns a typed pointer. Memory must be explicitly freed using delete.
Basic Usage Example
int* createInt() {
int* val = new int(40);
return val;
}
int main() {
int* ptr = createInt();
cout << *ptr << endl;
delete ptr; // Critical cleanup
return 0;
}
Array Allocation
For arrays, use delete[] to properly deallocate memory:
int main() {
int* array = new int[5];
for(int i = 0; i < 5; i++) {
array[i] = i * 10;
}
delete[] array; // Array-specific deallocation
return 0;
}