CERT.MEM.OBJ_LIFETIME_DTOR

Object with manually allocated memory not explicitly destroyed

The CERT.MEM.OBJ_LIFETIME_DTOR checker looks for user-defined objects, whose memory is dynamically allocated without the new operator, that have a non-trivial destructor call which is not explicitly called.

Vulnerability and risk

If an object has a non-trivial destructor and its memory is allocated on the heap, then deallocating the memory without explicitly calling the destructor or using the delete operator will result in the destructor not being invoked. This is an issue if the destructor performs tasks such as destroying a resource it manages. Those operations will not happen without an explicit call to the destructor.

Mitigation and prevention

The compliant solution is to use the new and delete operators when managing memory since the delete operator will implicitly invoke the destructor of an object. On the other hand, remembering to explicitly call the destructor if it is non-trivial is another option.

Vulnerable code example

Copy
#include <cstdlib>
 
struct S {
  ~S() { /* operations to destroy the object properly*/ }
  void f();
};
 
void g() {
  S *s = static_cast<S *>(std::malloc(sizeof(S)));
   
  std::free(s);
}

Klocwork reports defect CERT.MEM.OBJ_LIFETIME_DTOR on line 9 stating that a "Dynamically allocated object pointed to by 's' is not destroyed by an explicit call to a destructor". In this code the user-defined destructor is not called implicitly so any operations it might have performed will no occur before the memory is freed.

Fixed code example

Copy
#include <cstdlib>
 
struct S {
  ~S() { /* operations to destroy the object properly */ }
};
 
void g() {
S *s = static_cast<S *>(std::malloc(sizeof(S)));
s->~S();
std::free(s);
}

The defect is now avoided since the code explicitly calls the destructor.

Related checkers