Memory should not be managed manually(Code Smell)
If you manage memory manually, it’s your responsibility to delete
all memory created with new
, and to make sure it’s delete
d once and only once. Ensuring this is done is error-prone, especially when your function can have early exit points.
Fortunately, the C++ language provides tools that automatically manage memory for you. Using them systematically makes the code simpler and more robust without sacrificing performance.
This rule raises an issue when you use:
new
- you should prefer a factory function that returns a smart pointer, such asstd::make_unique
or, if shared ownership is required,std::make_shared
,new[]
- you should prefer a container class, such asstd::vector
,delete
ordelete[]
- if you followed the previous advice, there is no need to manually release memory.
If your compiler does not support make_unique
, it’s easy to write your own:
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
Noncompliant Code Example
void f() {
auto c = new Circle(0, 0, 5);
c->draw();
delete c;
}
Compliant Solution
void f() {
auto c = make_unique<Circle>(0, 0, 5);
c->draw();
unique_ptr<Circle> c2{new Circle(0, 0, 5)}; // Clumsy, but still compliant by exception
}
Exceptions
If the result of a new is immediately passed as an argument to a function, we assume that the function takes ownership of the newly created object, and won’t raise an issue.
See
- C++ Core Guidelines R.11 - Avoid calling new and delete explicitly
- C++ Core Guidelines C.149 - Use unique_ptr or shared_ptr to avoid forgetting to delete objects created using new