C ++ локальная переменная и утечка памяти - PullRequest
0 голосов
/ 28 марта 2019

Я читаю кое-что вокруг и натолкнулся на это:

Деструкторы вызываются, когда переменная выходит из области видимости

Так что мой вопрос: что происходит с переменнымиу которых нет деструкторов?

Как пример:

class A {
    public:
        A () { }
};

void foo () {
    A a;
}

int main (void) {
    foo();
}

Так что в этом случае это a()?Разрушена ли память, выделенная для a после выполнения foo() или нет?

Чем у меня такой пример:

class A {
        std::vector <int> aa;
    public:
        A () : aa(5) { }
};

void foo () {
    A b;
}

int main (void) {
    foo();
}

В этом случае также выделяется память, которая была выделенадля b уничтожено после того, как foo() сделано или нет?

Еще одно уточнение, я знаю это:

class A {
    public:
        A () { }
};

эквивалентно

class A {
    public:
        A () { }
        inline ~A() = default;
};

Ноу меня вопрос, вызывается ли эта встроенная деструктура, когда foo() завершена?

EDIT: Когда был добавлен деструктор inline по умолчанию?

Ответы [ 2 ]

2 голосов
/ 28 марта 2019

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

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

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

Хотя я делаю для всех таких ресурсов то, что я делаю класс, который оборачивает ресурс и имеет деструктор, который закрывает его. Это локализует проблему, поэтому я должен помнить как можно меньше об управлении ресурсами для большей части моего кода. Это распространенная идиома в C ++ и называется RAII , что означает «Инициализация ресурсов - это инициализация».

Именно поэтому вы должны предпочесть make_unique и make_shared или что-то вроде vector выделению памяти с помощью new. Они дают вам объекты, которые обертывают ресурс памяти, и деструкторы автоматически освобождают его для вас.

Чтобы ответить на вопрос в вашем комментарии к моему ответу более подробно ...

Деструктор локальной переменной вызывается, как только элемент управления покидает блок, в котором он был объявлен. Для конкретного примера:

void foo () {
    A b;
    {
        A c;
    } // Destructor for c is called here
} // Destructor for b is called here.
1 голос
/ 28 марта 2019

С стандарт :

Если класс не имеет деструктора, объявленного пользователем, деструктор неявно объявляется как дефолт ([dcl.fct.def]) .Неявно объявленный деструктор является inline public членом своего класса.

Другими словами,

class A {
    public:
        A () { }
};

эквивалентен

class A {
    public:
        A () { }
        inline ~A() = default;
};

Asна ваш вопрос

Но мой вопрос заключается в том, называется ли эта встроенная деструкция, когда foo() завершена?

Ответ - да.Однако это верно даже для пользовательского деструктора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...