Как справиться со статическими объектами при перегрузке новых и удалить, чтобы найти утечки памяти? - PullRequest
0 голосов
/ 27 мая 2009

Я пытаюсь обнаружить утечки памяти, глобально перегружая new и delete для отладочных сборок и поддерживая список выделенных блоков. Это работает, но неправильно сообщает об утечках для некоторых статических объектов. Например, сам статический std :: vector не выделяется с помощью new и delete, а его внутренние буферы. Поскольку мой код обнаружения выполняется до того, как основная функция возвращает, деструкторы этих объектов еще не вызваны, поэтому они еще не удалили свои буферы, и это выглядит как «утечка».

Один из обходных путей, который я нашел, - это удаление и размещение новых статических объектов для очистки их буферов перед проверкой на утечки:

std::vector<int> f;

f.~std::vector<int>();
new (&f) std::vector<int>();

Это действительно уродливо, хотя включать код очистки, который не требуется, кажется плохим. Есть ли способ заставить мой код работать после того, как статика была уничтожена? (даже если это специфично для Microsoft)

Ответы [ 4 ]

2 голосов
/ 27 мая 2009

Вам нужно взглянуть на std::allocator - второй параметр шаблона почти для всех контейнеров STL.

1 голос
/ 27 мая 2009

Поместите весь свой код обнаружения утечки в другую, отдельную DLL. Затем убедитесь, что код, который вы хотите проверить на утечки, зависит от DLL. Это позволяет загрузчику убедиться, что «DLL-библиотека проверки утечки» инициализируется до всего остального, а также выгружается после всего остального. Это обеспечит выполнение кода проверки утечки после того, как весь другой код был выгружен (и вызваны деструкторы).

Это метод, который я использовал при создании Визуальный детектор утечек , и, похоже, он работает хорошо.

1 голос
/ 27 мая 2009

Напишите функцию, которая очищает ваш список выделенных блоков. Вызывайте его после статической инициализации, но до того, как ваша программа начнет выделять все, что вы хотите отслеживать. Первым делом в main () следует это сделать. Конечно, вы по-прежнему будете видеть утечки для статических векторов, размер которых изменился, поэтому вы можете зарезервировать их больше, чтобы начать в режиме обнаружения утечек. Если статический вектор неумолимо растет со временем, то вы, вероятно, хотите знать об этом и рассматривать его как утечку, даже если он статический.

Редактировать в ответ на комментарий:

Например, вместо одного центрального бита кода для уничтожения всех глобальных переменных во время выключения:

template<typename T> 
class Reserve {
     Reserve(T &t, typename T::size_type size) {
         t.reserve(size);
     }
};

static std::vector<int> foo;
static Reserve<std::vector<int> > foo_r(foo, 50);

static std:string bar;
static Reserve<std::string> bar_r(bar, 256);

Возможно, вы можете что-то сделать с шаблоном функции, чтобы вывод типа избавил от необходимости повторять тип. Как насчет:

template<typename T>
int reserve(T &t, typename T::size_type size) {
    t.reserve(size);
    return 0;
}

static std::vector<int> foo;
static int foo_r = reserve(foo, 50);

static std:string bar;
static int bar_r = reserve(bar, 256);
0 голосов
/ 27 мая 2009

Вы можете попробовать использовать обработчик atexit .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...