Что такое утечка памяти?

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

Таким образом, вот то, что я (думаю), что понимаю. Исправления очень приветствуются!

При первом запуске программы блок памяти выделяется, скажите 0x000 0xFFF. Первая часть (говорят, что 0x000 к 0x011) код/сегмент текста, где код программы загружается.

+--------------+ 0x011
| Program Code |
+--------------+ 0x000

Затем у Вас есть стек (скажите, что 0x012 к 0x7ff), который содержит локальные переменные, и они хранятся/получаются FIFO. Таким образом, если у Вас было что-то как

char middleLetter(string word){
     int len = word.length();
     return word[len/2];
}

int main(){
   int cool_number;
   char letter;
   letter = middleLetter("Words");
   ...

Затем Ваши переменные были бы выделены на стеке, который будет похож на это:

+-------------+ 0x7ff
|             |
|             |
|             |
| ...         |
| len         |
| letter      |
| cool_number |
+-------------+ 0x012

Конечно, если Вы выделяли память где-нибудь (использование malloc или new), но никогда не освобождая его, затем Ваша "куча" могла быть похожей на это, и у Вас теперь есть утечка памяти:

+-------------+ 0xfff
|             |
| malloc(20)  | 0xf64
| malloc(50)  | 0xf32
| malloc(50)  | 0xf00
| ...         |
|             |
+-------------+ 0x800

То, что это означает, - то, что, в то время как можно непосредственно получить доступ к 0xf32 с адресной арифметикой с указателями, программа ОС/Вашей думает, что ячейки памяти 0xf00-0xf46 уже взяты и никогда не будут использовать те пятна для устройства хранения данных снова, пока программа не закрывается, и память освобождена. Но что относительно общей памяти? Википедия говорит, что никогда не будет выпускаться (пока Ваш компьютер не будет перезапущен?). Как Вы знаете, является ли это общая память?

Действительно ли это - довольно хорошее основное понимание? Есть ли что-нибудь, что я пропускаю / неправильно? Спасибо за взгляд!

25
задан Billy ONeal 8 June 2011 в 01:50
поделиться

6 ответов

Похоже, вы это понимаете, за одним исключением: в вашем примере len является переменной стека, как и все остальное. new или malloc создают в куче, все остальное (локальные переменные и т. Д.) Находится в стеке. И локальные переменные main не отличаются от переменных любой другой функции.

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

9
ответ дан 28 November 2019 в 21:42
поделиться

Утечка памяти стала проще : всякий раз, когда вы выделяете память с помощью malloc / new и не освобождаете ее позже с помощью команды free / delete после завершения использования этой памяти ... вызовет утечку памяти! Выделенная память останется там, и это пространство больше не будет использоваться вашей программой.

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

4
ответ дан 28 November 2019 в 21:42
поделиться

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

  1. Вызов некоторой функции F
  2. F выделяет (new или malloc) некоторую память
  3. F возвращает вызывающему абоненту (без удаления / освобождения)
  4. указатель, указывающий на динамически выделяемую память, отсутствует объема
    • память все еще выделена.
    • Вы больше не можете удалить / освободить его
6
ответ дан 28 November 2019 в 21:42
поделиться

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

Возьмем типичное приложение, скажем, программу чтения RSS-новостей. В таком приложении часто бывает много циклов (циклический переход по разным RSS-каналам, различным RSS-элементам, RSS-тегам и т. Д.). Если у вас есть экземпляр, в котором созданный объект не был должным образом уничтожен (или освобожден), каждый раз, когда запускается этот «утекающий» код, вы будете получать еще один брошенный объект в памяти. Если цикл выполняется 1000 раз, у вас будет 1000 брошенных объектов, занимающих место. Вы можете видеть, как это может быстро накапливаться, чтобы потреблять ценные ресурсы.

4
ответ дан 28 November 2019 в 21:42
поделиться

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

3
ответ дан 28 November 2019 в 21:42
поделиться

Похоже, вы используете код на C++. В C++ локальные переменные помещаются в стек (я предполагаю, что и глобальные тоже, но не уверен). Поэтому len в вашей функции middleLetter также будет помещена в стек вызовов. Я рекомендую прочитать эту статью: http://en.wikipedia.org/wiki/Call_stack

Когда вы используете оператор new с типом, например, int *x = new int;, находится достаточно непрерывной памяти, чтобы поместить int. Указатель, который вы используете для ссылки на него, *x, является локальной переменной. Если x выходит из области видимости и вы теряете указатель, это не освобождает память на куче. Эта память все еще "используется" вашей программой, хотя теперь у вас нет возможности на нее сослаться. Поскольку вы не можете на нее сослаться, вы не можете ее деаллоцировать (или удалить).

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

3
ответ дан 28 November 2019 в 21:42
поделиться
Другие вопросы по тегам:

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