Как обнаружить двойное удаление или удаление на нераспределенной памяти в C ++? - PullRequest
4 голосов
/ 13 июня 2011

Я пишу отладочные версии глобального оператора удаления / нового для обнаружения утечек памяти, двойного удаления и удаления на нераспределенной памяти.

Что касается оператора "новый", я отверг глобальный новыйоператор и с помощью макросов я передал имя файла и информацию о номере строки.Переопределенный оператор «new» сохраняет информацию об адресе памяти, имени файла, размере и номере строки в карте с указанием адреса.

Я также переопределил оператор «delete», который удаляет запись удаленного адреса с карты.Теперь я хочу сохранить информацию об удаленной памяти на другой карте, в которой хранится информация об имени файла и номере строки, откуда был вызван «delete».

Но оператор удаления принимает только аргумент (адрес памяти объекта длябыть удаленным).Может кто-нибудь сказать, как обнаружить двойное удаление в коде?

Ответы [ 3 ]

6 голосов
/ 13 июня 2011

Вы уже создаете карту выделенных адресов памяти (ключ) и имени файла, номера строки (поля значений) внутри вашей перегруженной new.

Пока вы перегружены, удалите, просто проверьте, существует ли передаваемый адрес на созданной вами карте.

Если да, Вы считаете вызов delete действительным и удаляете эту запись адреса из своей карты.

Если Нет, то вызов удаления должен быть ошибочным, delete called on a pointer not allocated through your new илиtrying to call delete multiple times.

2 голосов
/ 13 июня 2011

Если вам нужно отличить двойное удаление от удаления из никогда не выделенной памяти, просто сопоставьте адреса с состоянием выделенной памяти, вместо удаления элемента из карты, просто обновите состояние , чтобы пометить его как уже выпущенный . Тест при каждом удалении будет проверять, присутствует ли адрес (если не ошибка удаляет никогда не выделенный адрес), и если да, то была ли память уже освобождена (если она есть, то ошибка является двойной свободной).

0 голосов
/ 13 июня 2011

Есть две отдельные проблемы: обнаружение двойного удаления (в отличие для удаления памяти, которая никогда не была выделена, и определения, где в Программа это произошло. Во-первых, моя отладка operator new выделяет охранные зоны перед и после блока он возвращается (также используется для обнаружения записи после конец на освобождении); Я установил для них другой шаблон в operator delete и проверю этот шаблон. Всегда есть шанс, что никогда не выделяемая память может содержать этот шаблон, но вероятность очень, очень маленький Определить, где в коде произошла ошибка, сложнее. Я написал код, который выполняет обход стека, но он очень системный зависимый. (У меня есть версии для Solaris на Sparc, Linux на Intel и Windows.) И все, что он сообщает, это адреса возврата в шестнадцатеричном виде; это до программист, чтобы проанализировать те, используя другие инструменты. GNU binutils пакет имеет программу addr2line, которая хорошо работает под Linux, но это не так сложно сделать вручную, учитывая отсортированную карту.

...