причина утечки памяти в C C++

каковы причины утечки памяти в C C++ (кроме обычного выделения памяти и забудьте освободить ее)

8 ответов


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

void f1() {
    int* ptr = new int;

    // do something which may throw an exception

    // we never get here if an exception is thrown
    delete ptr;
}

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


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

например, следующий код вызывает утечку памяти в размере sizeof(int):

int * a = malloc(sizeof(int)); //allocate memory
a = 0; //this will cause a memory leak

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


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


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

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

в любом случае, если вы хотите избежать утечек памяти в C++, следуйте этим правилам:

  • предпочитают передавать ссылки, а не указатели
  • по возможности используйте smart pointer (см.:shared_ptr)

A new без delete, a new[] без delete[], a malloc без free.

серьезно, что еще вы хотите услышать?


нет никакой другой причины для утечки памяти, кроме той, которую вы упомянули


Я удивлен, что никто еще не упомянул о повреждении памяти.

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

какой-то парень перепутал вычисления размера, что привело к копированию данных всего на пару байтов за пределами максимального размера блока (указатели были только 2 байта в то время :)). Затем он перезапишет ссылку" next", расположенную в начале следующего свободного блока, мусором, который был заполнен обнуляет.

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

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


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

при нажатии кнопки:

  Get some memory, which will be used to remember the floor number
  Put the floor number into the memory
  Are we already on the target floor?
    If so, we have nothing to do: finished
    Otherwise:
      Wait until the lift is idle
      Go to the required floor
      Release the memory we used to remember the floor number

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