Skip to content

Memory_best_practices

This chapter covers best practices for efficient and safe memory management in C++.

┌─────────────────────────────────────────────────────────────┐
│ Memory Management Best Practices │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. Prefer Smart Pointers over Raw Pointers │
│ 2. Use RAII for Resource Management │
│ 3. Avoid Raw new/delete in Application Code │
│ 4. Prefer std::vector over Dynamic Arrays │
│ 5. Use std::array for Fixed-Size Arrays │
│ 6. Minimize Pointer Aliasing │
│ 7. Use std::move to Avoid Unnecessary Copies │
│ 8. Profile Before Optimizing Memory │
│ │
└─────────────────────────────────────────────────────────────┘
// Bad: Raw pointer
void process() {
Resource* r = new Resource();
// Might throw before delete!
delete r;
}
// Good: Smart pointer
void process() {
auto r = std::make_unique<Resource>();
// Automatically deleted when goes out of scope
}
class FileHandler {
FILE* file;
public:
FileHandler(const char* name) {
file = fopen(name, "r");
}
~FileHandler() {
if (file) fclose(file);
}
};
// Bad
int* arr = new int[100];
// ... use arr ...
delete[] arr;
// Better: Use std::vector
std::vector<int> arr(100);
// No manual management needed!
// If must: At least use smart pointer
auto arr = std::make_unique<int[]>(100);
// Bad: Multiple pointers to same memory
int* p1 = new int(42);
int* p2 = p1;
*p2 = 100; // Affects p1 too - confusing!
delete p1; // p2 is now dangling!
// Better: Clear ownership
auto p1 = std::make_unique<int>(42);
auto p2 = *p1; // Copy instead
*p2 = 100; // p1 is unchanged
// Use sanitizers
// Compile with: -fsanitize=address -fsanitize=leak
// Or use Valgrind
// valgrind --leak-check=full ./program
  • Use smart pointers for all dynamic allocations
  • RAII ensures automatic cleanup
  • Profile memory before optimizing
  • Use sanitizers during development