Как назначить имя переменной в #define (Boost related Mem Leak)? - PullRequest
0 голосов
/ 01 июля 2011

Я запустил Memory Validator в приложении, которое мы разрабатываем, и обнаружил, что определенные нами макрокоманды являются причиной около 90% утечек. #define O_set.

Теперь наши макросы определены следующим образом:

#define O_SET_VALUE(ValueType, Value) boost::shared_ptr<ValueType>(new ValueType(Value))
.
.
#define O_set O_SET_VALUE

Однако, согласно веб-сайту Boost (по адресу: http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/shared_ptr.htm):

Простое руководство, которое почти исключает возможность памяти Утечки есть: всегда используйте именованный смарт переменная указателя для хранения результата новый. Каждый случай нового Ключевое слово в коде должно иметь форма: shared_ptr p (новый Y); Это, конечно, приемлемо использовать другое умный указатель вместо shared_ptr выше; с одинаковыми T и Y введите или передайте аргументы Y конструктор тоже в порядке.

Если вы соблюдаете это руководство, оно естественно следует, что у вас будет нет явных удалений; попробуй поймать конструкции будут редкими.

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

Вопрос в том, есть ли способ обойти упомянутую проблему с помощью приведенного выше макроса #defines?

Обновление: Я использую их, например, так:

return O_set(int, 1); _time_stamp(O_set(TO_DateTime, TO_DateTime())) (_time_stamp является членом определенного класса)

Я работаю в Windows и использовал MemoryValidator для отслеживания утечек памяти - в соответствии с этим есть утечки - как я утверждаю, корень большинства из которых (согласно следам стека) сводится к этому макросу #define.

1 Ответ

0 голосов
/ 01 июля 2011

Умные указатели хитры. Первое, что я хотел бы сделать, это проверить ваш код на наличие любого «нового» оператора, которого нет ни в одном макросе.

Тогда вам нужно подумать о том, как используются указатели; если вы передадите умный указатель по ссылке, то счетчик ссылок не увеличится, например.

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

Кроме того, вы можете подумать, почему вы используете макрос для создания всех интеллектуальных указателей. Увеличить поставку различных умных указателей для разных целей. Существует не один размер подходит для всех решений. Старый добрый std :: auto_ptr подходит для большинства случаев, за исключением хранения в стандартных контейнерах, но вы уже это знали.

Самый очевидный и упускаемый из вида аспект заключается в том, действительно ли вам необходимо что-то «новое». C ++ - это не Java, если вы можете избежать создания динамических объектов, вам лучше это делать.

Если вам повезло работать с * платформой NIX (вы не упоминаете, извините), попробуйте инструмент проверки утечек с Valgrind. Это очень полезно. Существуют аналогичные инструменты для Windows, но часто лучше использовать программное обеспечение.

Удачи.

...