2010-08-03 2 views
1

Примечание: Это может звучать глупо. У меня есть приложение, которое использует необработанные указатели, и в приложении много утечек памяти.Замена существующих исходных указателей на интеллектуальные указатели

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

Чтобы объяснить немного дальше, это приложение является устаревшим, и есть очень простые утечки памяти, где память будет выделена и не будет выпущена в той же самой функции.

Я провел анализ памяти с помощью DevPartner и нашел много областей. Является Valgrind лучше, чем Devpartner.

ответ

3

Использование интеллектуальных указателей, несомненно, станет хорошим началом для очистки вашего приложения, но это не лекарство. Многие утечки памяти могут быть просто небрежностью в хорошо продуманной программе, но, скорее всего, у вас серьезные проблемы с дизайном, и утечка памяти является симптомом этого. Когда вы переключаетесь на интеллектуальные указатели, вам все равно придется делать такие варианты дизайна, как «Кто владеет этим объектом», «Является ли владение этим объектом, разделенным между несколькими клиентами», и «Каково ожидаемое время жизни этого объекта», чтобы выбрать правильная реализация интеллектуального указателя для данного сценария. Но это будет хороший способ начать, потому что процесс выбора правильного вкуса умного указателя для разных ситуаций заставит вас задуматься об этих вещах и, вероятно, улучшит ваш дизайн.

1

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

Редактировать: Чтобы получить преимущества интеллектуальных указателей, вам также необходимо подключить или реализовать собственный сборщик мусора, поскольку он не является языковой функцией.

Редактировать 2: Умные указатели, по-видимому, реализуют подсчет ссылок, что является стратегией сбора мусора.

+1

Умные указатели - это не то же самое, что сбор мусора. –

+0

ах, хороший момент. отметил :-) – gtrak

+1

Вам не нужен сборщик мусора со смарт-указателем, если у вас нет цикла в вашей модели. Вам просто нужно разбить цикл с помощью обычного указателя. Я использовал умный указатель в течение многих лет и никогда не должен реализовывать gc и любые утечки памяти. – mb14

2

Нет сомнений в том, что умные указатели уменьшают нагрузку на проблемы с памятью программиста w.r.t. Поскольку вы не упомянули, является ли это устаревшим приложением или как легко изменить интерфейсы (не всегда требуемые, поскольку интеллектуальные указатели деградируют до необработанных указателей), я бы предложил запустить приложение под каким-то инструментом, например valgrind (на Linux) или очистить (в Unices и Windows), чтобы отслеживать утечку памяти.

По моему опыту, большинство утечек памяти следуют определенной схеме (разработчик A пропускает что-то, разработчик B копирует этот код и вместе с ним проблему). Таким образом, используя инструменты, вы можете решить проблемы с утечкой памяти, прежде чем думать об использовании интеллектуальных указателей.

И если вы начинаете разрабатывать это приложение - начните с использования интеллектуальных указателей. Они сэкономит вам много времени и энергии на линии.

0

Документы с интеллектуальными указателями в коде "владение объектами. Поэтому для каждого указателя вы должны преобразовать «неопределенный документ, который был в некоторых главах программистов» в этот «точный документ в коде». Большинство вариантов легко. Это все еще оставляет много вариантов, которых нет. Кроме того, помимо владения, вам нужно беспокоиться о том, чтобы разбить циклы объектов объекта со слабыми указателями. Таким образом, это общее преобразование в интеллектуальные указатели не является тривиальной задачей, и если вы ошиблись в части, связанной с циклом, вы даже представите новые утечки памяти.

+0

Единственное, что есть в документе с умными указателями: «Мне все равно, кому принадлежит этот объект, просто убедитесь, что он правильно уничтожен в конце». Вы не представляете, кто ссылается на объект, вы также не знаете, когда последняя ссылка выйдет за пределы области видимости, поэтому вы не знаете, когда объект будет уничтожен. В общем, вы понятия не имеете о жизни объекта, потому что нет ни одного владельца. Каждому принадлежит объект (потому что каждый клиент может его уничтожить), поэтому никто не владеет объектом. Таким образом, «собственность» не документирована вообще. –

+0

Я думаю, что вы немного смущены приравниванием «собственности» к «собственности только одним объектом». В большинстве случаев код (подразумевает или подразумевает) совместное владение. Когда вы говорите (потому что каждый клиент может его уничтожить), с умным указателем никто не может его уничтожить, просто отпустите право собственности. – jyoung

+0

@Frerich Вы, кажется, ссылаетесь на определенный тип умного указателя, указатель с подсчетом ссылок, но есть разные типы умных указателей для разных сценариев владения. См. Http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/smart_ptr.htm. Если вкус умного указателя хорошо выбран для конкретной ситуации, это отличный способ документировать стратегию владения объектами в коде. – bshields

2

Я собираюсь дать это фирме «очень возможно».

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

Другая форма, в которой выделен объект, а собственность разделяется, а это означает, что существует более одной процедуры, которая ее использует, и нет простого способа рассказать, все ли с ней связаны. Это хороший кандидат для shared_ptr, но вам нужно проявлять осторожность. При создании объекта присвойте shared_ptr и убедитесь, что каждый другой указатель использует shared_ptr. Если подпрограммы A, B и C обращаются к объекту через shared_ptr, и вы не изменили D, тогда, когда выполняются процедуры A, B и C, он уходит, независимо от потребностей D.

Одна вещь, которую вы хотите, чтобы избежать с shared_ptr это количество циклов, так как если я есть shared_ptr к J, J имеет shared_ptr для К и К имеет shared_ptr к I, ни один из них не когда-либо будут удалены, даже если они недоступны нигде в программе. Вам нужно следить за этими ситуациями. Вы можете разбить их на weak_ptr в цикле или удалить элемент в цикле самостоятельно или просто жить с утечкой.

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

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

Смежные вопросы