Ugrás a tartalomhoz

Szerkesztő:LinguisticMystic/cpp/DynamicMemoryAllocation

A Wikiszótárból, a nyitott szótárból

🔍 Understanding Memory Allocation in C++

[szerkesztés]

In C++, memory allocation is essential for storing variables, objects, and data structures. There are three main types of memory allocation:



📌 1. Static Memory Allocation

[szerkesztés]
  • When: At compile time.
  • How: Memory size and type must be known in advance.
  • Examples: Global variables and static variables.
int globalVar = 10; // Static memory allocation
  • Memory Location: Data segment (initialized/uninitialized).
  • Lifetime: Allocated when the program starts, and deallocated when it ends.



📌 2. Automatic Memory Allocation

[szerkesztés]
  • When: At runtime, managed by the compiler.
  • How: Happens when you declare local variables inside functions.
void myFunction() {
    int localVar = 5; // Automatic memory allocation
}
  • Memory Location: Stack.
  • Lifetime: Allocated when the function is called and deallocated when it returns.

You don’t need to explicitly manage it — the compiler handles it automatically.



📌 3. Dynamic Memory Allocation

[szerkesztés]
  • When: At runtime, managed manually by the programmer.
  • How: Using new and delete operators.
int* ptr = new int; // Allocates memory dynamically
*ptr = 42;
delete ptr;        // Deallocates the memory
  • Memory Location: Heap.
  • Lifetime: You decide when to allocate and deallocate.

⚠️ If you forget to call delete, you get a memory leak.



🧠 Why Use Dynamic Memory?

[szerkesztés]

Imagine writing a game where the player can choose how many heroes to include in their team:

❌ Automatic Memory Allocation Problem

[szerkesztés]
void startGame() {
    Hero team[100];  // Always allocates memory for 100 heroes
}
  • If the user only wants 5 heroes, you waste memory.
  • If the user wants 101 heroes, this will fail (overflow risk).



✅ Dynamic Memory Allocation Solution

[szerkesztés]
void startGame() {
    int numHeroes;
    std::cout << "Enter number of heroes: ";
    std::cin >> numHeroes;

    Hero* team = new Hero[numHeroes]; // Allocate exactly the needed size

    // ... use the team

    delete[] team;  // Deallocate when done
}

✅ This allocates only the amount of memory needed. ⚠️ It’s your job to free the memory using delete[].



🛠 Using new and delete

[szerkesztés]

🔹 Allocate a single integer:

[szerkesztés]
int* ptr = new int;   // Allocate
*ptr = 7;
delete ptr;           // Deallocate

🔹 Initialize at the time of allocation:

[szerkesztés]
int* ptr = new int(5); // Allocates and initializes to 5

🧮 Example: Dynamic Array

[szerkesztés]
#include <iostream>

int main() {
    int size;
    std::cout << "Enter the size of the array: ";
    std::cin >> size;

    int* arr = new int[size];  // Allocate dynamic array

    for (int i = 0; i < size; ++i) {
        arr[i] = i * 2;
        std::cout << "Array element " << i << " is " << arr[i] << std::endl;
    }

    delete[] arr; // Free the memory

    return 0;
}

🧾 Output (for input 5):

[szerkesztés]
Array element 0 is 0
Array element 1 is 2
Array element 2 is 4
Array element 3 is 6
Array element 4 is 8

This dynamically allocates memory for the array based on user input.



💡 Best Practices

[szerkesztés]

✅ Always match new with delete and new[] with delete[]

[szerkesztés]
int* p = new int;
delete p; // ✅ OK

int* a = new int[10];
delete[] a; // ✅ OK

❌ Never access memory after it’s deallocated

[szerkesztés]
delete p;
*p = 42; // ❌ Undefined behavior!

🚨 Memory Leaks

[szerkesztés]

Memory leaks occur when allocated memory is not freed:

for (int i = 0; i < 100000000; ++i) {
    int* ptr = new int;
    // ... logic ...
    delete ptr;  // ❗ Omitting this would cause a leak
}

Without delete, the program gradually consumes RAM — eventually exhausting system resources.



🧱 Handling Allocation Failures

[szerkesztés]

By default, if new fails, it throws std::bad_alloc.

try {
    int* bigArray = new int[1000000000000];
} catch (std::bad_alloc& e) {
    std::cerr << "Memory allocation failed: " << e.what() << std::endl;
}

Or use nothrow to avoid exceptions:

int* ptr = new(std::nothrow) int;
if (ptr == nullptr) {
    std::cout << "Allocation failed.\n";
}

🧪 Null Pointers

[szerkesztés]

A pointer not pointing to any memory is called a null pointer:

int* ptr = nullptr;
if (ptr == nullptr) {
    std::cout << "Pointer is null.\n";
}

New returns nullptr if it fails (in nothrow mode).



✅ Conclusion

[szerkesztés]
Type When Allocated Memory Area Managed By Needs Manual delete?
Static Compile time Data Segment Compiler ❌ No
Automatic Function call Stack Compiler ❌ No
Dynamic Runtime Heap Programmer ✅ Yes
  • Use static/automatic memory when size is fixed and known in advance.
  • Use dynamic memory when:
    • You don’t know the size ahead of time.
    • You need memory across function calls or for large data.
  • Always delete what you new, or face memory leaks!