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

У нас есть собственный класс умных указателей, который подсчитывается с использованием базовых AddRef и Release.

Во время отладки я вижу, что многие объекты не высвобождаются должным образом. Я могу видеть, какие объекты не освобождаются, но трудно определить, из какого места они выделены.

Есть ли хороший шаблон дизайна для решения этой проблемы?

Я поместил отладочные операторы и ADDREF и RELEASE, и я могу видеть счетчик ссылок, когда вызывается release. В некоторых случаях это больше, чем 1, это означает, что указатель не удаляется.

Если я начну устанавливать точки останова на const shared_ptr, то он будет вызываться сотни раз, и его будет трудно определить утечку памяти.

Похоже, что создаются некоторые циклические ссылки, которые вызывают эти утечки.

0

Решение

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

Используйте инструмент памяти. На ум приходит Valgrind, и ряд коммерческих для Windows.

Также…

Я могу видеть, какие объекты не освобождаются, но трудно определить, из какого места они выделены.

Зачем? Установите точку останова в конструкторе объекта. Или вместо этого используйте стандартные указатели (std::shared_ptr, std::unique_ptr).

Согласно вашему редактированию:

Я поместил отладочные операторы и ADDREF и RELEASE, и я могу видеть счетчик ссылок, когда вызывается release. В некоторых случаях это больше, чем 1, это означает, что указатель не удаляется.

Принимаете ли вы во внимание возможность копирования (RVO / NRVO)? Это, скорее всего, является причиной.

2

Другие решения

Лет назад, до auto_ptrЯ написал свой собственный класс интеллектуальных указателей, который мы широко использовали в нашей кодовой базе. Конечно, это был биток, полный ошибок.

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

Первым делом я написал #define макрос> дрожь<похож на тот, который я обрисовал Вот, который я мог бы использовать вместо new выделить мои объекты. Макрос отправил дополнительные параметры интеллектуальному указателю, указывающему файл & номер строки сайта вызова. Умный указатель сохранит это.

Затем я заменил глобальный new с моим макросом, когда я произнес волшебное заклинание #defines Включение этой функции. Очевидно, что это должно быть отключено во всех сборках Releasse и использоваться только в сборках отладки, когда вы на самом деле отлаживаете этот.

Затем я позволил моей программе работать, пока не добрался до точки, где я хотел видеть все сайты вызовов. Я бы выполнил dump_call_sites() метод на смарт-указатель там, который сбросил static vector строк сайта вызова в стандартный вывод. Следовательно, проблема найдена, я бы отменил все эти магические заклинания, чтобы отключить все эти hokus pokus.

Это действительно хак-н-слэш кодификация. Это далеко не элегантно, и это создает свой собственный набор проблем. Но наряду с printf отладка, у нее есть свое место. Если вы не хотите или не можете загружать свой продукт типа Rational Purify или Bounds Checker, это может помочь вам быстро определить, откуда происходят ваши утечки.

1

По вопросам рекламы [email protected]