Как вы должны тестировать современный C ++ на предмет утечек памяти?
Примеры юнит-тестов обычно выглядят так:
TestCase {
Instantiate testObject
testObject->AllocateSomeResources
testObject->PerformATest
testObject->DeallocateResources
Destroy testObject
}
Мы используем valgrind для обнаружения утечек памяти. Это очень эффективно, если распределение ресурсов выполняется с new
и delete
, но когда ресурсы хранятся в виде интеллектуальных указателей внутри стандартных контейнеров, автоматическая очистка при уничтожении testObject не позволяет нам обнаруживать ошибки.
Когда система работает. Контейнеры ресурсов могут расти со временем из-за неправильной процедуры освобождения. Было бы тривиально выяснить, было ли выделение выполнено с new
и delete
.
Существуют ли какие-либо методы, которые исправят этот аспект современного C ++?
Идеи:
- Сделать все деструкторы проверенными на выделенные ресурсы. Это немного повлияет на базу производственного кода.
- Создание более отдельных и проверяемых процедур выделения и освобождения. Конечно, но так как мы получили это «бесплатно» с более традиционным C ++, я все же хотел бы найти альтернативы.
Очевидно, я вижу преимущество в стандартных контейнерах и умных указателях, извините зазаголовок наживки
Редактировать
Пример:
class A {
int* resource;
public:
void allocate(){ resource = new int; }
void deallocate(){ /*delete resouce;*/ }
};
class B {
std::unique_ptr<int> resource;
public:
void allocate(){ resource = std::make_unique<int>(); }
void deallocate(){ /*resource.reset();*/ }
};
И класс A, и B имеют один и тот же недостаток. Ошибка в функции deallocate заставляет их удерживать память, в которой они не нуждаются после вызова deallocate. С классом А это «фактическая утечка» и ее тривиально обнаружить, например, с помощью Valgrind в модульном тесте. Для класса B я могу только обнаружить недостаток в модульном тесте, выставив частный ресурс как публичный, что я не хочу делать. Этот вопрос не о Valgrind, а о том, существуют ли шаблоны, которые помогут мне получить продукт того же качества, который я достиг бы с Valgrind и классом A, но использующие стандартные контейнеры и умные указатели для хранения моих личных ресурсов.
Участвующие объекты могут жить неделями, с разным количеством ресурсов, выделенных в течение этого времени.