Main Content

AUTOSAR C++14 Rule A18-5-2

Non-placement new or delete expressions shall not be used

Since R2020a

Description

Rule Definition

Non-placement new or delete expressions shall not be used.

Rationale

Explicit use of nonplacement new or delete operators might result in memory leaks caused by unexpected exceptions or returns. Consider this code where memory is allocated for a pointer by explicitly calling new and deallocated by explicitly calling delete.

std::int32_t ThrowError(){
	std::int32_t errorCode;
	std::int31_t* ptr = new std::int32_t{0};
	//...
	if(errorCode!=0){
		throw std::runtime_error{"Error"};
	}
	//...
	if (errorCode != -1) {
		return 1;  
	}
	delete ptr;  
	return errorCode;
}
This code can lead to unexpected memory leak in certain conditions.

  • If the first if() statement is true, then the function produces an exception and exits without deleting the pointer.

  • If the second if() statement is true, then the function returns 1 and exits without deleting the pointer.

To avoid an unpredictable memory leak, do not use nonplacement new and delete operators. Instead, encapsulate dynamically allocated resources in objects. Acquire the resources in object constructors and release the resources in object destructors. This design pattern is called "Resource Acquisition Is Initialization" or RAII. Following the RAII pattern prevents a memory leak even when there are unexpected exceptions and returns.

Alternatively, use manager objects that manage the lifetime of dynamically allocated resources. Examples of manager objects in the standard library include:

  • std::unique_ptr along with std::make_unique

  • std::shared_ptr along with std::make_shared

  • std::string

  • std::vector

This rule does not apply to a new operator or a delete operator in user-defined RAII classes and managers.

Polyspace Implementation

AUTOSAR C++14 permits explicit resource allocation by calling the new operator in two cases, when the allocated resource is immediately passed to:

  • A manager object

  • A RAII class that does not have a safe alternative to the new operator.

Polyspace® flags all explicit uses of the new operator and the delete operator. If you have a process where a new operator can be permissible and there is no safer alternative, justify the issue by using comments in your result or code. See:

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

This code shows how Polyspace flags new or delete operators.

#include <cstdint>
#include <memory>
#include <vector>
#include <cstddef>

using namespace std;

int32_t Fn1()
{
	int32_t errorCode{0};
	int32_t* ptr =
	new int32_t{0}; //Noncompliant
	// ...
	if (errorCode != 0) {
		throw  runtime_error{"Error"}; // Possible Memory Leak
	}
	// ...
	if (errorCode != 0) {
		return 1; //Possible Memory Leak
	}
	// ...
	delete ptr; //Noncompliant

	return errorCode; // Possible Memory Leak
}

int32_t Fn2()
{
	int32_t errorCode{0};
	// Alternative to 'new'
	unique_ptr<int32_t> ptr1 = make_unique< int32_t>(0); 
	unique_ptr<int32_t> ptr2(new  int32_t{0});   // Noncompliant
	shared_ptr<int32_t> ptr3 =
	make_shared<int32_t>(0);   //Compliant
	vector<int32_t> array;   // Compliant

	if (errorCode != 0) {
		throw  runtime_error{"Error"};   // No memory leaks
	}
	// ...
	if (errorCode != 0) {
		return 1; // No memory leaks
	}
	// ...
	return errorCode; // No memory leaks
}


class X
{
public:
	static void* operator new( size_t s)
	{
		return ::operator new(s);   // Noncompliant
	}

	static void* operator new[]( size_t s)
	{
		return ::operator new(s);   // Noncompliant
	}

	static void operator delete(void* ptr,  size_t s)
	{
		::operator delete(ptr);   // Noncompliant
	}

	static void operator delete[](void* ptr,  size_t s)
	{
		::operator delete(ptr);   // Noncompliant
	}
};

main(){
	X* x1    = new X;   // Noncompliant
	X* x2    = new X[2];   // Noncompliant
}

In Fn1(), the operators new and delete are explicitly called for resource management. Consequently, an unexpected exception or return can lead to a memory leak. Polyspace flags the new and delete operators. In Fn2(), manager objects are used for memory management. Even in cases of unexpected exceptions and returns, there are no memory leaks in Fn2().

The class X contains custom overloads for new and delete operators. Polyspace flags all instances of new and delete operators in the definitions of the custom overloads. In main(), Polyspace also flags the overloaded new and delete operators.

Check Information

Group: Language support library
Category: Required, Partially automated

Version History

Introduced in R2020a