CERT.MEM.OBJ_LIFETIME_CTOR

Uninitialized heap member function call

The CERT.MEM.OBJ_LIFETIME_CTOR checker looks for user-defined objects, whose memory is dynamically allocated without the new operator, that invoke a member function without first being initialized.

Vulnerability and risk

If an object is allocated on the heap without using the new operator, for example using malloc, and it does not have a trivial constructor, then the object is uninitialized. Invoking a member function of that object is considered undefined behavior because the lifetime of the object has not yet started. Use of uninitialized objects typically leads to unpredictable behavior, and may have security implications.

Mitigation and prevention

The compliant solution is to allocate memory using the new operator since it will also invoke the constructor. Another option is to explicitly invoke the constructor once the memory has been allocated.

Vulnerable code example

Copy
#include <cstdlib>
 
struct S {
  S(){}
  void f(){}
};
 
void g() {
  S *s = static_cast<S *>(std::malloc(sizeof(S)));
  s->f();
  std::free(s);
}

Klocwork reports defect CERT.MEM.OBJ_LIFETIME_CTOR on line 10 stating that a "Pointer to uninitialized dynamically allocated object 's' is used to call a member function 'f'". In this code the member function 'f' is called before the object has been initialized

Fixed code example

Copy
#include <cstdlib>
 
struct S {
  S(){}
  void f(){}
};
 
void g() {
  S *s = static_cast<S *>(std::malloc(sizeof(S)));
  s = new (s) S;
  s->f();

  std::free(s);
}

The defect is now avoided since the code explicitly calls the constructor so the lifetime of the object begins before it is used.