In modern C++ programming, it's generally recommended to avoid raw pointers for several reasons related to safety, clarity, and maintainability.
Raw pointers do not manage memory automatically. This puts the onus on us as developers to ensure the lifecycles of our objects are managed correctly. If we don’t accomplish thise, our program can have several problems.
If you forget to call delete
on a dynamically allocated object, you'll leak memory. For example:
void LeakyFunction() {
int* p = new int(42);
// Missing delete
}
Here, the allocated memory is not freed, leading to a memory leak.
After delete
is called, the pointer still holds the address of the freed memory, which can lead to undefined behavior if accessed.
void DanglingFunction() {
int* p = new int(42);
delete p;
*p = 10;
}
Raw pointers can make code harder to understand and maintain:
Modern C++ provides smart pointers like std::unique_ptr
and std::shared_ptr
that handle memory management automatically.
std::unique_ptr
This manages a resource with exclusive ownership, ensuring the resource is deleted when the unique_ptr
goes out of scope.
void SafeFunction() {
std::unique_ptr<int> p{
std::make_unique<int>(42)};
}
Here, the memory is automatically freed when p
goes out of scope.
std::shared_ptr
This manages a resource with shared ownership, deleting the resource only when the last shared_ptr
to it is destroyed.
void SharedFunction() {
std::shared_ptr<int> p1{
std::make_shared<int>(42)};
// Both share ownership
std::shared_ptr<int> p2{p1};
}
Using smart pointers helps avoid common pitfalls with raw pointers and makes your code safer and easier to manage.
Answers to questions are automatically generated and may not have been reviewed.
Learn the techniques and pitfalls of manual memory management in C++