Это считается утечкой памяти?

Общее правило, только объекты, размещенные в бесплатном хранилище, могут вызвать утечку памяти. Но объекты, созданные в стеке, этого не делают.

Вот мое сомнение,

int main()
    {
      myclass x;

      ...

      throw;

      ...
    }

Если throw не обрабатывается, он вызывает метод terminate(), который, в свою очередь, вызывает abort() и завершает работу приложения. В это время объекты в стеке не уничтожаются (деструктор не вызывается).

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

Я прав?

7 ответов

Решение

В размещенной среде (например, в типичной для вас Unix / Windows / Mac OS X, даже DOS, машине), когда приложение завершает всю занятую память, она автоматически возвращается операционной системой. Поэтому беспокоиться о таких утечках памяти не имеет смысла.

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

В общем, отказ от вызова деструктора - это не то же самое, что утечка памяти. Утечки памяти происходят из памяти, выделенной в куче (с новыми или malloc или распределителями контейнера). Память, выделенная в стеке, автоматически восстанавливается при размотке стека. Однако, если объект содержит какой-либо другой ресурс (например, файл или дескриптор окна), отказ от вызова его деструктора вызовет утечку ресурса, что также может быть проблемой. Опять же, современные ОС вернут свои ресурсы после завершения работы приложения.

Редактировать: как упомянуто GMan, "бросить;" перебрасывает ранее выброшенное исключение или, если его нет, немедленно завершается. Поскольку в этом случае их нет, результатом является немедленное завершение.

Завершение процесса всегда очищает любую оставшуюся пользовательскую память в любой современной ОС, поэтому, как правило, это не считается "утечкой памяти", которая определяется как не связанная с памятью память, не выделяемая в работающем процессе. Тем не менее, операционная система должна решать, считать ли это "утечкой памяти".

Ответ, это зависит от ОС. Я не могу думать о современной ОС, которая не делает это таким образом. Но старые системы (я думаю, чтобы выиграть 3.1 в Windows, и некоторые старые встраиваемые платформы Linux), если программа закрылась, не освобождая свои запросы памяти, ОС удерживала их до тех пор, пока вы не перезагрузились.

Реальный вопрос: "Распределяет ли myclass саму память, которая должна быть свободна / удалена?"

Если это не так - если единственная память, которую он использует, это ее внутренние члены - тогда она полностью существует в стеке. Как только он покидает эту функцию (как бы то ни было), память в стеке восстанавливается и используется повторно. myclass ушел Именно так работают стеки.

Если myclass выделяет память, которая должна быть освобождена в его dtor, то вам все же повезло, так как dtor будет вызван, так как стек разматывается во время броска. Dtor будет вызван до того, как исключение будет объявлено необработанным, и будет вызвано завершение.

Единственное место, где у вас будут проблемы, это если у myclass есть dtor, и dtor выбрасывает как исключение своего собственного. Второй бросок, происходящий во время разматывания стека после первого броска, приведет к немедленному завершению его вызова без вызова дополнительных dtors.

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

От ОП,

Если throw не обрабатывается, он вызывает метод terminate (), который, в свою очередь, вызывает abort() и завершает работу приложения. В это время объекты в стеке не уничтожаются (деструктор не вызывается).

Это поведение, определяемое реализацией.

$ 15.3 / 9- "Если в программе не найден соответствующий обработчик, вызывается функция terminate (); независимо от того, разматывается ли стек до того, как этот вызов terminate () будет определен реализацией (15.5.1)".

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

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

Я прав?

Утечка памяти - это тип ошибки программирования, который оценивается несколько ниже по шкале ошибок программирования - по сравнению с неперехваченным исключением.

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

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

Другие вопросы по тегам