CWE Rule 460
Description
Rule Description
The product does not clean up its state or incorrectly cleans up its state when an exception is thrown, leading to unexpected state or control flow.
Polyspace Implementation
The rule checker checks for Exception violating class invariant.
Examples
Exception violating class invariant
This issue occurs when a non-noexcept
member function attempts to
raise an exception after modifying any of the fields of the class. For instance,
Polyspace® flags a throw()
statement or a new
statement if they are used after modifying the internal state of a class.
To facilitate recovery from an exception while preserving the invariant of the relevant objects, design programs that have exception safety. The C++ standard allows these levels of exception safety:
Basic Exception Safety: This level of exception safety requires that after raising an exception, the basic invariants of all objects are maintained in a valid state and no memory is leaked. If an operation has basic exception safety, then you can destroy or assign to an object after the operations, even if an exception has been raised. The operations in the standard library offer at least basic exception safety.
Strong Exception Safety: This level of exception safety requires that after raising an exception, the state of the program remains as it was before the exception. Operations with strong exception safety either succeed or exit with an exception and have no effects on the program.
nothrow
: This level of safety requires that an exception cannot occur in an operation.
Without at least the basic exception safety, exceptions might corrupt the state of a program, leave the program in an invalid state, or create memory leaks. Code that does not provide at least the basic exception safety guarantee is unsafe and defective.
To provide at least the basic exception safety in a function, modify the class invariant only when there can be no exceptions. When performing actions that might raise exceptions, use temporary objects that do not modify the original objects invariant.
#include <cstdint> #include <cstring> template<typename T=int> class myArray { public: myArray() {/*...*/} myArray(const myArray& rhs) { DeepCopyNC(rhs); } ~myArray() { delete[] array; } void DeepCopyNC(const myArray& rhs) // Noncompliant { if (this != &rhs) { delete[] array; array = nullptr; len = rhs.len; if (len > 0) { array = new T[len]; std::memcpy(array, rhs.array, len * sizeof(T)); } } } private: T* array; std::size_t len; }; extern myArray<> c1{}; void foo() { myArray<> c2{c1}; }
This example shows a generic class template myArray
that manages a
raw array. The copy constructor of this class shows two implementation of deep copy. In
the function DeepCopyNC()
, the memory operations are performed after
modifying the this->array
and this->len
fields. If
the memory operation exits with an exception, the invariant of the original class is
violated. Because the class invariant is violated by an exception, the function
DeepCopyNC()
cannot guarantee basic exception safety. Polyspace flags it.
To guarantee basic exception safety, modify the class invariant only when the memory
operation succeeds with no exceptions, as shown in DeepCopy
.
#include <cstdint> #include <cstring> template<typename T=int> class myArray { public: myArray() {/*...*/} myArray(const myArray& rhs) { DeepCopy(rhs); } ~myArray() { delete[] array; } void DeepCopy(const myArray& rhs) // Compliant { T* eTmp = nullptr; if (rhs.len > 0) { eTmp = new T[rhs.len]; std::memcpy(eTmp, rhs.array, rhs.len * sizeof(T)); } delete[] array; array = eTmp; len = rhs.len; } private: T* array; std::size_t len; }; extern myArray<> c1{}; void foo() { myArray<> c2{c1}; }
Check Information
Category: Initialization and Cleanup Errors |
Version History
Introduced in R2023a
See Also
External Websites
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)