Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

In the first alternative (delete object), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined. In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.

Do not destroy delete an object of derived class type through a pointer to its base class type that has a non-virtual destructor. Instead, the base class should be defined with a virtual destructor. Deleting an object through a pointer to a type without a virtual destructor results in undefined behavior.

Noncompliant Code Example

In this noncompliant example, b is a polymorphic pointer type whose static type is Base * and whose dynamic type is Derived *. When b is destroyddeleted, it results in undefined behavior because Base does not have a virtual destructor. According to the C++ Standard, [class.dtor], paragraph 4 [ISO/IEC 14882-2014 ]:

...

Code Block
bgColor#FFCCCC
langcpp
struct Base {
  virtual void f();
};
 
struct Derived : Base {};
 
void f() {
   Base *b = new Derived();
   // ...
   delete b;
}

Compliant Solution

In this compliant solution, the destructor for Base has an explicitly declared virtual destructor, ensuring that the polymorphic destroy delete operation results in well-defined behavior. To guard against subclasses of Derived not having access to a virtual destructor, Derived is marked as a final class so that it cannot be further inherited from.

Code Block
bgColor#ccccff
langcpp
struct Base {
  virtual ~Base() = default;
  virtual void f();
};

struct Derived final : Base {};

void f() {
   Base *b = new Derived();
   // ...
   delete b;
}

Risk Assessment

Attempting to destruct a polymorphic object that does not have a virtual destructor declared results in undefined behavior. In practice, potential consequences include abnormal program termination and memory leaks.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

OOP52-CPP

Low

Likely

Low

P9

L2

Automated Detection

Tool

Version

Checker

Description

PRQA QA-C++

Include Page
PRQA QA-C++_V
PRQA QA-C++_V

2116, 3403

 
Klocwork
Include Page
Klocwork_V
Klocwork_V
CL.MLK.VIRTUAL 
Clang
Include Page
Clang_V
Clang_V
-Wdelete-non-virtual-dtor 
LDRA tool suite
Include Page
LDRA_V
LDRA_V

303 S

Partially implemented

Parasoft C/C++test9.5OOP-22 
SonarQube C/C++ Plugin
Include Page
SonarQube C/C++ Plugin_V
SonarQube C/C++ Plugin_V
S1235 

Related Vulnerabilities

Search for other vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

Bibliography

[ISO/IEC 14882-2014]

Subclause 5.3.5, "Delete"
Subclause 12.4, "Destructors" 

[Stroustrup 06]"Why Are Destructors Not Virtual by Default?"

...