// Leak — every new needs a matching delete
int* p = new int(5);
// forgot: delete p; <-- leak!
// Fix: use smart pointers
auto p = make_unique<int>(5);
// auto-freed when p goes out of scope
Tools: Valgrind (Linux/macOS), AddressSanitizer (-fsanitize=address), Visual Studio Diagnostic Tools.
Exercise
Implement a RAII class MemoryBlock that allocates a dynamic array of N ints in its constructor and frees it in its destructor. Use it to store and print 5 values.
Show Solution
#include <iostream>
using namespace std;
class MemoryBlock {
private:
int* data;
int size;
public:
MemoryBlock(int n) : size(n), data(new int[n]) { cout << "Allocated\n"; }
~MemoryBlock() { delete[] data; cout << "Freed\n"; }
int& operator[](int i) { return data[i]; }
int getSize() { return size; }
};
int main() {
MemoryBlock block(5);
for (int i = 0; i < block.getSize(); i++) block[i] = i * 10;
for (int i = 0; i < block.getSize(); i++) cout << block[i] << " ";
cout << endl;
return 0;
}
Quiz
What keyword deallocates a heap array?
A) delete ptr
B> free(ptr)
C) delete[] ptr
D> remove(ptr)
Answer
C) delete[] — use delete[] for arrays allocated with new[].
Summary
Stack is fast and automatic; heap is flexible but must be managed.
Always pair new with delete, and new[] with delete[].
RAII wraps resources in objects with constructors/destructors.
Prefer smart pointers to eliminate memory leaks entirely.