AUTOSAR C++14 Rule A18-5-2

Выражения без размещения или удаления не должны использоваться

Описание

Определение правила

Выражения без размещения или удаления не должны использоваться.

Объяснение

The new оператор выделяет память. The delete оператор освобождает память. Если вы используете эти операторы явно, необходимо связать их, чтобы избежать утечки памяти. Даже тогда неожиданные исключения или возвраты могут привести к утечке памяти. Рассмотрим этот код, где память выделяется для указателя явным вызовом new и отменяется явным вызовом 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;
}
Хотя и new оператор связан со delete оператор, этот код может привести к утечке памяти в определенных обстоятельствах.

  • Если первый if() оператор true, затем функция создает исключение и выходит, не удаляя указатель мыши.

  • Если второй if() оператор true, затем функция возвращается 1 и выходит без удаления указателя.

Чтобы избежать непредсказуемой утечки памяти, инкапсулируйте ресурсы, такие как динамически выделенная память или указатели на файлы, в объекты. Получите ресурсы в конструкторах объектов и отпустите ресурсы в деструкторах объектов. Этот шаблон проекта называется «Resource Acquisition Is Initialization» или RAII. Следование шаблону RAII предотвращает утечку памяти даже в случае неожиданных исключений и возвратов.

Кроме того, используйте объекты manager, которые управляют временем жизни динамически выделенных ресурсов. Примеры объектов менеджера в стандартной библиотеке включают:

  • std::unique_ptr наряду с std::make_unique

  • std::shared_ptr наряду с std::make_shared

  • std::string

  • std::vector

Это правило не применяется к new оператор или delete оператор в пользовательских классах RAII и менеджерах.

Реализация Polyspace

AUTOSAR C++ 14 позволяет явное выделение ресурсов путем вызова new оператор в двух случаях, когда выделенный ресурс немедленно передается:

  • Объект менеджера

  • Класс RAII, который не имеет безопасной альтернативы new оператор.

Polyspace® флаги всех явных применений new оператор и delete оператор. Если у вас есть процесс, где new оператор может быть допустим, и нет более безопасной альтернативы, обосновать проблему, используя комментарии в вашем результате или коде. Смотрите Адрес Результаты Polyspace через исправления ошибок или обоснования.

Поиск и устранение проблем

Если вы ожидаете нарушения правил, но не видите его, обратитесь к разделу «Стандартные нарушения кодирования не отображаются».

Примеры

расширить все

Этот код показывает, как Polyspace флаги new или delete операторы.

#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
}

В Fn1(), операторы new и delete явно вызываются для управления ресурсами. Следовательно, неожиданное исключение или возврат могут привести к утечке памяти. Polyspace помечает new и delete операторы. В Fn2()Объекты менеджера используются для управления памятью. Даже в случаях неожиданных исключений и возвратов нет утечек памяти в Fn2().

Класс X содержит пользовательские перегрузки для new и delete операторы. Polyspace помечает все образцы new и delete операторы в определениях пользовательских перегрузок. В main () Polyspace также помечает перегруженные новые и удаляют операторы.

Проверяйте информацию

Группа: Библиотека языковой поддержки
Категория: Требуемая, Частично автоматизированная
Введенный в R2020a