Могу ли я иметь утечки памяти, если я не использую новое ключевое слово? - PullRequest
0 голосов
/ 24 января 2019

Я новичок в языке, и у меня есть базовые сомнения по поводу утечек памяти. Возможна ли утечка, если я не использую ключевое слово new? (то есть наличие переменных в стеке и использование контейнеров данных, таких как std::vector)

Должен ли я беспокоиться об этой проблеме?

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

Ответы [ 3 ]

0 голосов
/ 24 января 2019

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

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

Например, malloc выделяет блок памяти. Также calloc резервирует память и обнуляет ее.

Ваша работа может также дать вам методы для управления памятью. Например strdup для Linux.

Вы также можете использовать умные указатели и вызывать std::make_unique или std::make_shared. Оба метода динамически распределяют память.

Для std::unique_ptr вы можете получить утечку, если позвоните release() и забудете удалить указатель.

 std::make_unique<int>(3).release(); // Memory leak

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

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

Например, рассмотрим следующий код:

#include <iostream>
#include <string>
#include <vector>

void f() 
{
    static std::vector<int> v;
    v.insert(v.begin(), 100*1024*1024, 0);
    v.clear();
}

int main()
{
    f();
    return 0;
}

std::vector::clear() не требуется для освобождения памяти, выделенной вектором. Таким образом, после вызова f() у вас будет выделено 400 МБ памяти, но только внутри f(). Не совсем утечка памяти, но это выделенный ресурс, который не освобождается автоматически до конца.

0 голосов
/ 24 января 2019

В дополнение к другим ответам, легким источником утечек памяти являются внешние библиотеки. Многие из них, особенно C или C-подобные библиотеки, имеют функции типа create_* и destroy_* для своих типов данных. Даже если вы никогда не вызываете явным образом new, утечка памяти так же проста.

0 голосов
/ 24 января 2019

то есть наличие моих переменных в стеке и использование контейнеров данных, таких как std::vector

Нет, с std::vector или другими стандартными контейнерами, вам не нужно беспокоиться.

Может ли кто-нибудь привести пример ситуации, которая создает утечку без динамического выделения памяти?

Одной из распространенных ошибок являются циклически зависимые умные указатели вида:

class Child;
class Parent {
     std::vector<std::shared_ptr<Child>> childs;
};

class Child {
     std::shared_ptr<Parent> parent;
};

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

Дополнительную информацию о причинах этого и о том, как его избежать, можно найтиздесь

...