Memory and Garbage Collector in C++: Why Your Code Does Not Forgive Mistakes
\n\nWhen a developer transitions to C++ after Python, Java, or C#, they often face a cold shower. Where before you could simply create an object and forget about it (thanks to the garbage collector!), in C++ you have to think about every byte. And this is not a bug, but a feature. C++ does not forgive laziness, but gives you absolute control over memory in return — and, as a result, over performance.
\n\nIn this article, we will analyze why C++ has no built-in garbage collector (GC), how manual memory management works, and what modern tools (RAII, smart pointers) allow you to write safe and fast code without headaches. If you write in C++ or are just starting out — this material is for you.
\n\nMyth #1: C++ has a garbage collector
\n\nLet's dispel the main misconception right away. Standard C++ (ISO C++98/11/14/17/20/23) has no built-in garbage collector. Yes, you can connect an external library (for example, libgc by Hans Boehm), but this will be a crutch, not a native mechanism. Why?
- \n
- C++ philosophy: "You don't pay for what you don't use." The garbage collector consumes resources (CPU, memory) and introduces non-deterministic pauses. For real-time systems, games, embedded — this is deadly. \n
- Determinism: In C++, you know exactly when an object will be destroyed. In GC — you don't (only "sometime"). \n
- RAII (Resource Acquisition Is Initialization) — this is our "garbage collector", but manual and predictable. \n
How manual memory management works in C++
\n\nThe classic: new and delete. Allocated memory on the heap — don't forget to free it.
#include <iostream>\n\nint main() {\n int* p = new int(42); // allocated memory for an int\n std::cout << *p << std::endl;\n delete p; // freed — otherwise a leak\n return 0;\n}\n\nSeems simple? Now imagine that between new and delete an exception, a return, or someone forgetting to call delete can occur. We get the classic C++ memory leak. And this is just the beginning: double delete, dangling pointers — that's where the real hell is.
RAII — the best friend of a C++ developer
\n\nRAII is not just an abbreviation, it's a way of life in C++. The idea: a resource (memory, file, mutex) is acquired in the constructor and released in the destructor. As soon as the object goes out of scope — the destructor is called automatically. Guaranteed.
\n\nExample with the smart pointer std::unique_ptr:
#include <memory>\n#include <iostream>\n\nclass MyClass {\npublic:\n MyClass() { std::cout << "Created\\n"; }\n ~MyClass() { std::cout << "Destroyed\\n"; }\n};\n\nint main() {\n std::unique_ptr<MyClass> ptr = std::make_unique<MyClass>();\n // No delete! Memory will be freed automatically when exiting the block\n return 0;\n}\n\nOutput: Created, then Destroyed. No leaks, no manual calls. RAII replaces the garbage collector in C++ — but does it predictably and without pauses.
Smart pointers: unique_ptr, shared_ptr, weak_ptr
\n\nIf you are still using raw new/delete — stop. Modern C++ (starting from C++11) offers smart pointers that automate memory management.
std::unique_ptr
\nExclusive ownership. Cannot be copied, only moved. Ideal for sole ownership of a resource.
\n\nstd::unique_ptr<int> p1 = std::make_unique<int>(10);\n// std::unique_ptr<int> p2 = p1; // Error! Copying is forbidden\nstd::unique_ptr<int> p2 = std::move(p1); // Ok, transfer of ownership\n\n