Когда вы считаете, что программа протекает, и вам нужно освободиться до выхода? [Дубликат]

Для тех, кто находит это в будущем, я бы не рекомендовал использовать mail. Есть несколько ответов, которые касаются этого, но не из-за этого.

Функция PHP mail не только непрозрачна, но и полностью зависит от того, какой MTA вы используете (то есть Sendmail) для выполнения этой работы. mail будет ТОЛЬКО сообщать вам, не удалось ли MTA принять его (т. е. Sendmail был отключен, когда вы пытались отправить). Он не может сказать вам, была ли почта успешной, потому что она была передана. Как таковой (как детали ответов Джона Конде), вы теперь можете возиться с журналами MTA и надеяться, что он расскажет вам об отсутствии возможности исправить его. Если вы находитесь на общем хосте или не имеете доступа к журналам MTA, вам не повезло. К сожалению, по умолчанию для большинства ванильных инсталляций для Linux обрабатывается так.

Почтовая библиотека ( PHPMailer , Zend Framework 2+ и т. д.) делает что-то очень отличное от mail. То, что они делают, это открыть сокет непосредственно на принимающем почтовом сервере, а затем отправить SMTP-почтовые команды непосредственно через этот сокет. Другими словами, класс действует как собственный MTA (обратите внимание, что вы можете сказать библиотекам использовать mail, чтобы в конечном итоге отправить почту, но я настоятельно рекомендую вам не делать этого).

Что это означает, что вы можете непосредственно видеть ответы с принимающего сервера (например, в PHPMailer вы можете включить вывод отладки ). Больше не гадать, если почта не была отправлена ​​или почему.

Если вы используете SMTP (то есть вы вызываете isSMTP()), вы можете получить подробную расшифровку протокола SMTP, используя свойство SMTPDebug.

Установите этот параметр, включив в свой скрипт такую ​​строку:

$mail->SMTPDebug = 2;

Вы также получаете преимущество лучшего интерфейса. С помощью mail вы должны настроить все свои заголовки, вложения и т. Д. С библиотекой у вас есть специальная функция для этого. Это также означает, что функция выполняет все сложные элементы (например, заголовки).

436
задан Toby Speight 20 April 2016 в 09:32
поделиться

17 ответов

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

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

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

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

305
ответ дан Paul Tomblin 21 August 2018 в 23:25
поделиться
  • 1
    Вероятно, было бы неплохо также упомянуть, что не все используют современную операционную систему, если кто-то берет вашу программу (и она все еще работает на ОС, которая не восстанавливает память) запускает ее тогда GG. – user105033 12 November 2009 в 20:48
  • 2
    Я действительно считаю этот ответ неправильным. Один должен всегда освобождать ресурсы после того, как с ними делается, будь то файловые дескрипторы / память / мьютексы. Имея эту привычку, никто не ошибается при создании серверов. Ожидается, что на некоторых серверах будет работать 24x7. В таких случаях любая утечка любого типа означает, что ваш сервер в конечном итоге исчерпает этот ресурс и каким-то образом зависает. Короче говоря, полезная программа, и утечка не так уж плоха. Любой сервер, любая утечка - смерть. Сделай себе одолжение. Очистите себя. Это хорошая привычка. – EvilTeach 31 December 2009 в 23:15
  • 3
    Какая часть «Тем не менее, считается хорошим стилем для освобождения памяти, как только она вам больше не понадобится, и чтобы освободить все, что у вас есть на выходе программы». вы считаете неправильным? – Paul Tomblin 31 December 2009 в 23:37
  • 4
    Если у вас есть хранилище памяти, которое вам нужно прямо до момента выхода программы, и вы не работаете на примитивной ОС, освобождение памяти непосредственно перед выходом - это стилистический выбор, а не дефект. – Paul Tomblin 2 January 2010 в 13:49
  • 5
    @Paul - просто соглашаясь с EvilTeach, не считается хорошим стилем для освобождения памяти, неверно не освобождать память. Ваша формулировка делает это так же важным, как носить платок, который соответствует вашему галстуку. На самом деле, он находится на уровне ношения брюк. – Heath Hunnicutt 24 June 2011 в 19:17

Вполне нормально оставлять память свободной при выходе; malloc () выделяет память из области памяти, называемой «кучей», и полная куча процесса освобождается, когда процесс завершается.

Как говорится, одна из причин, по которой люди все еще настаивают на том, что это чтобы освободить все до выхода, - это то, что отладчики памяти (например, valgrind on Linux) обнаруживают разблокированные блоки как утечки памяти, и если у вас также есть «настоящие» утечки памяти, становится сложнее их обнаружить, если вы также получаете «поддельные» результаты в конце.

11
ответ дан Antti Huima 21 August 2018 в 23:25
поделиться
  • 1
    Не делает Valgrind довольно хорошую работу, различая «утечку», и "все еще достижимый"? – Christoffer 17 March 2009 в 16:39
  • 2
    -1 для "полностью тонкой" Плохая практика кодирования оставляет выделенную память, не освобождая ее. Если этот код был извлечен в библиотеку, это приведет к появлению memleaks повсюду. – DevinB 17 March 2009 в 16:52
  • 3
    -1 для "полностью тонкой" – NTDLS 19 March 2009 в 21:03
  • 4
    +1 для компенсации. См. Ответ компилятора. free в exit время считается вредным. – R.. 29 January 2012 в 06:55

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

Редактирование: на 100% невозможно сказать, что другие запущенные программы лишены этой памяти. Операционная система всегда позволяет им использовать ее за счет замены вашей программы на виртуальную память (</handwaving>). Дело в том, что если ваша программа освобождает память, которую она не использует, смену виртуальной памяти с меньшей вероятностью необходимо.

11
ответ дан Bill the Lizard 21 August 2018 в 23:25
поделиться

Да, вы правы, ваш пример не наносит вреда (по крайней мере, не в большинстве современных операционных систем). Вся память, выделенная вашим процессом, будет восстановлена ​​операционной системой после завершения процесса.

Источник: Распределение и мифы GC (оповещение PostScript!) [/ ​​g2]

Миф о распределении 4: программы, не содержащие мусор, должны всегда освобождать всю память они выделяют.

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

В большинстве случаев освобождение памяти непосредственно перед выходом программы бессмысленно. ОС все равно вернет его. Свободная воля коснется и занесет страницы в мертвые объекты; ОС не будет.

Следствие: будьте осторожны с «датчиками утечки», которые подсчитывают распределения. Некоторые «утечки» хороши!

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

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

92
ответ дан Csq 21 August 2018 в 23:25
поделиться
  • 1
    Получает ли этот ответ специальный значок для принятого ответа с отрицательными голосами? – Skizz 17 March 2009 в 16:45
  • 2
    Более того - почему имеет отрицательные голоса? Это неплохой ответ. – Kyle Cronin 17 March 2009 в 16:47
  • 3
    Возможно, потому что вопрос, как я его прочитал, - это то, что на самом деле происходит с просочившейся памятью, а не в том, соответствует ли этот конкретный пример. Я бы не проголосовал за это, потому что это хороший ответ. – DevinB 17 March 2009 в 16:49
  • 4
    Вероятно, были (ранние Windows, ранние Mac OS) и, возможно, еще есть ОС, которые требуют процессов для освобождения памяти перед выходом, иначе пространство не будет исправлено. – Pete Kirkham 17 March 2009 в 16:54
  • 5
    Я думаю, что неправильно объяснять необходимость свободного () «запоминания», говоря «из-за детектора утечки». Это как сказать «вам нужно медленно ехать на улицу, потому что полицейские могут ждать вас с помощью камеры с быстрой скоростью». – Sebastian Mach 24 March 2009 в 16:23

Каков реальный результат здесь?

Ваша программа просочилась в память. В зависимости от вашей ОС может быть восстановлен .

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

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

Возможно, вы работаете в режиме ядра или в винтажных / встроенных операционных системах, которые не используют защиту памяти как компромисс. (MMU занимают место в памяти, защита памяти требует дополнительных циклов процессора, и не так много, чтобы попросить программиста очистить после себя).

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

5
ответ дан DevSolar 21 August 2018 в 23:25
поделиться

Я полностью не согласен со всеми, кто говорит, что OP правильный или нет никакого вреда.

Все говорят о современной и / или устаревшей ОС.

Но что, если я ' m в среде, где у меня просто нет ОС? Где нет ничего?

Представьте, что теперь вы используете прерывания в стиле стилей и выделяете память. В стандарте C ISO / IEC: 9899 - это срок службы памяти, обозначенный как:

7.20.3 Функции управления памятью

1 Порядок и смежность памяти, выделенной последовательным вызовы функций calloc, malloc и realloc не определены. Указатель возвращается, если выделение успешно выполняется соответствующим образом, чтобы его можно было назначить указателю на любой тип объекта, а затем использовать для доступа к такому объекту или массиву таких объектов в выделенном пространстве (пока пространство явно не освобождено) , Время жизни выделенного объекта простирается от выделения до освобождения. [...]

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

Итак, другими словами: Не освобождение памяти - это не просто плохая практика. Он производит не переносимый, а не код соответствия. Который, по крайней мере, можно рассматривать как «правильный, если следующее: [...], поддерживается средой».

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

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

20
ответ дан dhein 21 August 2018 в 23:25
поделиться
  • 1
    Контр-аргумент заключается в том, что если вы являетесь встроенной средой, вы, как разработчик, в первую очередь будете более сообразительны в управлении памятью. Обычно это касается фактического предварительного выделения статической фиксированной памяти заранее, а не наличия каких-либо исполняемых команд mallocs / reallocs вообще. – John Go-Soco 21 April 2016 в 13:45
  • 2
    @lunarplasma: Хотя то, что вы говорите, не является неправильным, это не меняет того факта, о котором говорит стандарт языка, и все, кто действует против / дальше, может быть даже по здравому смыслу, производят ограниченный код. Я могу понять, если кто-то скажет «Мне не нужно заботиться об этом», так как достаточно случаев, когда все в порядке. НО что нужно хотя бы знать, ПОЧЕМУ ему не нужно заботиться. и особенно не опускать его, поскольку вопрос не связан с этим частным случаем. И поскольку ОП спрашивает о С вообще в теоретических (школьных) аспектах. Нехорошо сказать: «Вам не нужно». – dhein 21 April 2016 в 14:00
  • 3
    В большинстве сред, где нет ОС, нет средств, с помощью которых программы могут «завершаться». – supercat 14 October 2016 в 18:24
  • 4
    @supercat: Как я уже писал, вы правы. Но если кто-то спрашивает об этом в отношении преподавательских причин и школьных аспектов, то неправильно говорить «вам не нужно думать об этом в большинстве случаев, когда это не имеет значения». Формулировка и поведение определения языка даны по какой-то причине, и только потому, что большинство окружений обрабатывают его для вас, вы не можете сказать, что нет необходимости заботиться. Это моя точка зрения. – dhein 31 October 2016 в 13:42
  • 5
    -1 для цитирования стандарта C, в то время как большая часть из них НЕ применяется в отсутствие операционной системы, так как нет времени выполнения, чтобы обеспечить возможности стандартных мандатов, особенно в отношении управления памятью и стандартных библиотечных функций (которые также явно отсутствуют наряду с временем выполнения / ОС). – Nax 16 February 2017 в 01:58

Вы правы, никакого вреда не сделано, и быстрее выйти

. Для этого есть несколько причин:

  • Все настольные и серверные среды просто освобождают весь памяти на выходе (). Они не знают о внутренних структурах данных программы, таких как кучи.
  • Практически все free() реализации никогда не возвращают память в операционную систему.
  • Что еще более важно, это пустая трата времени, когда делалось прямо перед выходом (). При выходе страницы памяти и пространство подкачки просто освобождаются. В отличие от этого, серия бесплатных () вызовов будет записывать процессорное время и может привести к операциям пейджинга на диске, промахам кэш-памяти и выделению кеша.

Что касается возможности будущего использования кода, оправдывая определенность бессмысленных операций: это соображение, но это, возможно, не способ Agile . YAGNI!

44
ответ дан DigitalRoss 21 August 2018 в 23:25
поделиться
  • 1
    Я когда-то работал над проектом, где мы потратили небольшое количество времени, пытаясь понять использование памяти в программах (мы должны были его поддерживать, мы не писали его). Основываясь на опыте, я с неохотой соглашаюсь с вашей второй пулей. Однако я бы хотел, чтобы вы (или кто-то) предоставили больше доказательств того, что это правда. – user106740 28 December 2009 в 16:53
  • 2
    Неважно, нашел ответ: stackoverflow.com/questions/1421491/… . Спасибо тебе! – user106740 28 December 2009 в 17:10
  • 3
    +1 для запоминания того, что "будущая коррекция" это не всегда правильный путь. Подумайте дважды, прежде чем обобщать все. – aviggiano 29 January 2016 в 12:34
  • 4
    @aviggiano, который называется YAGNI. – v.oddou 11 May 2016 в 02:38
  • 5
    Принцип YAGNI работает в обоих направлениях: вам никогда не понадобится оптимизировать путь выключения. Преждевременная оптимизация и все такое. – Adrian McCarthy 24 April 2018 в 22:02

Если программа забывает освободить несколько мегабайт до того, как она выйдет из операционной системы, она освободит их. Но если ваша программа работает неделями, а цикл внутри программы забывает освободить несколько байтов на каждой итерации, у вас будет мощная утечка памяти, которая будет потреблять всю доступную память на вашем компьютере, если вы не перезагружаете ее на обычном basis => даже небольшие утечки памяти могут быть плохими, если программа используется для серьезной большой задачи, даже если она изначально не была предназначена для одного.

0
ответ дан Gunter Königsmann 21 August 2018 в 23:25
поделиться

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

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

3
ответ дан Kyle Cronin 21 August 2018 в 23:25
поделиться
  • 1
    Я хочу сказать -1 для вашего первого заявления и «нет опасности». за исключением того, что вы затем даете вдумчивый ответ о том, почему существует опасность. – DevinB 17 March 2009 в 16:54
  • 2
    Поскольку опасности идут, это довольно мягко - я возьму утечку памяти через segfault в любой день. – Kyle Cronin 17 March 2009 в 16:56
  • 3
    Очень верно, и мы оба предпочли бы ни = D – DevinB 17 March 2009 в 23:33
  • 4
    @KyleCronin Я бы much скорее имел segfault, чем утечку памяти, потому что обе серьезные ошибки и segfaults легче обнаружить. Слишком часто утечки памяти остаются незамеченными или неразрешенными, потому что они «очень мягкие». Моя ОЗУ и я всецело не согласны. – Dan Bechard 11 April 2016 в 17:49
  • 5
    @Dan Как разработчик, конечно. Как пользователь, я возьму утечку памяти. Я предпочел бы, чтобы программное обеспечение работало, хотя и с утечкой памяти, над программным обеспечением, которое этого не делает. – Kyle Cronin 11 April 2016 в 22:02

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

2
ответ дан Michael 21 August 2018 в 23:25
поделиться

Я думаю, что ваши два примера на самом деле только один: free() должен появиться только в конце процесса, который, как вы указываете, бесполезен, так как процесс завершается.

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

-2
ответ дан mouviciel 21 August 2018 в 23:25
поделиться

Если вы разрабатываете приложение с нуля, вы можете сделать некоторые образованные выборы о том, когда звонить бесплатно. Ваша примерная программа в порядке: она выделяет память, возможно, у вас есть ее работа на несколько секунд, а затем закрывается, освобождая все ресурсы, которые она требовала.

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

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

2
ответ дан ojrac 21 August 2018 в 23:25
поделиться

На самом деле есть раздел в онлайн-учебнике OSTEP для обучения студентов в операционных системах, в котором точно указан ваш вопрос.

Соответствующий раздел - «Забыть о свободной памяти» в в главе Memory API на стр. 6, которая дает следующее объяснение:

В некоторых случаях может показаться, что не вызов free () является разумным. Например, ваша программа недолговечна и скоро выйдет; в этом случае, когда процесс умирает, ОС очистит все выделенные страницы, и, таким образом, утечка памяти не произойдет сама по себе. Хотя это, безусловно, «работает» (см. в сторону на стр. 7 ), это, вероятно, плохая привычка развиваться, поэтому будьте осторожны в выборе такой стратегии

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

За кулисами операционная система будет переводить «виртуальные адреса», которые пользователь видит в фактических адресах, указывающих на физическую память.

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


EDIT: . Конец, упомянутый в выдержке, скопирован ниже.

ASIDE: ПОЧЕМУ НЕ УДАЛЕНА ПАМЯТЬ ПРОТИВ ПРОЦЕССА

Когда вы пишете короткий -lived, вы можете выделить некоторое пространство, используя malloc(). Программа запускается и собирается завершить: нужно ли free() вызвать кучу раз перед выходом? Хотя кажется неправильным, что никакая память не будет «потеряна» в каком-либо реальном смысле. Причина проста: в системе действительно два уровня управления памятью. Первый уровень управления памятью выполняется ОС, которая передает их в процессы, когда они запускаются, и возвращает их, когда процессы завершаются (или иначе умирают). Второй уровень управления находится внутри каждого процесса, например, внутри кучи, когда вы вызываете malloc() и free(). Даже если вам не удалось вызвать free() (и, таким образом, удалить память в куче), операционная система восстановит всю память процесса (включая эти страницы для кода, стека и, в зависимости от ситуации, кучу), когда программа закончен. Независимо от того, каково состояние вашей кучи в вашем адресном пространстве, ОС возвращает все эти страницы, когда процесс умирает, тем самым гарантируя, что память не будет потеряна, несмотря на то, что вы ее не освободили.

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

из Страница 7 из Справочника по API главы

Операционные системы: три простых пьесы Ремзи Х. Арпачи-Дуссе и Андреа К. Арпачи-Дуссеу Книги Арпачи-Дуссо Март, 2015 г. (версия 0.90)

2
ответ дан spenceryue 21 August 2018 в 23:25
поделиться

Обычно я освобождаю каждый выделенный блок, как только я уверен, что с ним все закончится. Сегодня точкой входа моей программы может быть main(int argc, char *argv[]), но завтра это может быть foo_entry_point(char **args, struct foo *f) и введено как указатель функции.

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

Что касается вашего второго вопроса, если моя программа взяла ввод, например a = 5, я бы выделил место для a или перераспределял одно и то же пространство на следующем a = "foo". Это оставалось бы распределенным до:

  1. Пользователь напечатал «unset a»
  2. . Была введена моя функция очистки, либо обслуживая сигнал, либо пользователь набрал «quit»

Я не могу придумать никакой современной ОС, которая не восстанавливает память после выхода процесса. Опять же, free () дешево, почему бы не убрать? Как говорили другие, такие инструменты, как valgrind, отлично подходят для обнаружения утечек, о которых вам действительно нужно беспокоиться. Несмотря на то, что блоки, на которые вы, например, будете помечены как «все еще доступные», просто лишний шум в выходе, когда вы пытаетесь обеспечить отсутствие утечек.

Еще один миф: « Если его в main (), мне не нужно его освобождать ", это неверно. Рассмотрим следующее:

char *t;

for (i=0; i < 255; i++) {
    t = strdup(foo->name);
    let_strtok_eat_away_at(t);
}

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

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

На самом деле, будьте добры к бедной душе, которая должна поддерживать ваши вещи, когда вы переходите к другим вещам .. передайте их им «valgrind clean»:)

19
ответ дан Tim Post 21 August 2018 в 23:25
поделиться
  • 1
    И да, однажды я сказал мне помощнику команды: «Мне не нужно звонить бесплатно () в main () & quot; & Lt; & вздрагивает GT; – Tim Post♦ 18 March 2009 в 09:44
  • 2
    free() is cheap, если у вас нет миллиарда структур данных со сложными отношениями, которые вы должны выпускать один за другим, перемещение структуры данных, чтобы попытаться выпустить все, может значительно увеличить время выключения, особенно если половина этой структуры данных уже выгружены на диск, без какой-либо выгоды. – Lie Ryan 20 March 2013 в 02:37
  • 3
    @LieRyan Если у вас миллиард, как в буквально миллиардных структур, у вас наиболее решительно есть другие проблемы, требующие особой степени рассмотрения - выход за рамки этого конкретного ответа :) – Tim Post♦ 25 August 2014 в 19:18

=== Как насчет будущей проверки и повторного использования кода? ===

Если вы не пишете код, чтобы освобождать объекты, тогда вы ограничиваете использование кода только безопасным, если вы можете зависеть от свободной памяти в процессе, являющемся закрытые ... т. е. небольшие одноразовые проекты или «отбрасывающие» [1] проекты) ... где вы знаете, когда процесс закончится.

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


[1] относительно проектов «выбросить». Код, используемый в проектах «Отбрасывание», имеет способ не выбрасываться. Следующее, что вы знаете, прошло десять лет, и ваш код «выкидывания» все еще используется).

Я слышал рассказ о каком-то парне, который написал какой-то код просто для удовольствия, чтобы улучшить его работу. Он сказал: « просто хобби, не будет большим и профессиональным ». Спустя годы многие люди используют свой «хобби» код.

49
ответ дан Trevor Boyd Smith 21 August 2018 в 23:25
поделиться
  • 1
    Сокращенный для «небольших проектов». Существует много крупных проектов, которые очень не хотят не освобождать память на выходе, потому что это пустая трата времени, если вы знаете целевые платформы. ИМО, более точным примером могли бы быть «изолированные проекты». Например. если вы создаете повторно используемую библиотеку, которая будет включена в другие приложения, то нет четко определенной точки выхода, поэтому вы не должны терять память. Для автономного приложения вы всегда будете точно знать, когда заканчивается процесс, и может принять осознанное решение отключить очистку ОС (что должно делать проверки в любом случае). – Dan Bechard 14 July 2017 в 16:10
  • 2
    Вчерашнее приложение является сегодняшней библиотечной функцией, а завтра оно будет связано с долговременным сервером, который называет его тысячами раз. – Adrian McCarthy 14 March 2018 в 23:01
  • 3
    @AdrianMcCarthy: если функция проверяет, является ли статический указатель нулевым, инициализирует его с помощью malloc(), если он есть, и завершает, если указатель все еще является нулевым, такую ​​функцию можно безопасно использовать произвольным числом раз, даже если free никогда не называется. Я думаю, что, вероятно, стоит различать утечки памяти, которые могут использовать неограниченное количество хранилищ, по сравнению с ситуациями, которые могут только тратить конечный и предсказуемый объем хранения. – supercat 24 April 2018 в 18:46
  • 4
    @supercat: Мой комментарий говорил о том, что кодекс меняется с течением времени. Конечно, утечка ограниченного объема памяти не является проблемой. Но когда-нибудь кто-то захочет изменить эту функцию, чтобы она больше не использовала статический указатель. Если в коде не предусмотрено освобождение памяти с заостренной памятью, это будет серьезное изменение (или, что еще хуже, изменения будут плохими, и вы получите неограниченную утечку). – Adrian McCarthy 24 April 2018 в 20:57
  • 5
    @AdrianMcCarthy: изменение кода, чтобы больше не использовать статический указатель, скорее всего, потребует перемещения указателя в какой-то «контекст». объект и добавление кода для создания и уничтожения таких объектов. Если указатель всегда null, если распределение не существует и не имеет значения null, когда существует выделение, с кодом, освобождающим выделение и устанавливающим указатель на null при уничтожении контекста, было бы просто, особенно по сравнению со всем остальным это необходимо сделать для перемещения статических объектов в структуру контекста. – supercat 24 April 2018 в 21:08

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

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

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

2
ответ дан Uri 21 August 2018 в 23:25
поделиться

Этот код, как правило, работает нормально, но рассмотрим проблему повторного использования кода.

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

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

Повторное использование кода типично для предприятий. Обычно компания владеет всем кодом, который производят его сотрудники, и каждый отдел может повторно использовать все, что принадлежит компании. Поэтому, написав такой «невинно выглядящий» код, вы вызываете потенциальную головную боль другим людям. Это может заставить вас уволить.

11
ответ дан WedaPashi 21 August 2018 в 23:25
поделиться
  • 1
    Возможно, стоит отметить возможность не только кого-то, копирующего фрагмент, но и возможность программы, которая была написана, чтобы сделать какое-то конкретное действие после того, как оно было изменено, чтобы сделать это повторно. В таком случае было бы хорошо, если бы память была распределена один раз , а затем использовалась повторно, не будучи освобожденной, но выделение и отказ от памяти для каждого действия (без ее освобождения) может быть катастрофическим. – supercat 15 November 2014 в 18:47
Другие вопросы по тегам:

Похожие вопросы: