Куча уничтожения классов и глобалов

Когда программа заканчивается, элементы в куче уничтожаются по порядку?

Что может быть результатом следующего сценария:

  1. создать класс a1, класс a1 содержит статические std::map
  2. создать деструктор класса b1, b1 распечатать содержимое карты
  3. вставить данные на карту

    std::string mapkey = "abcd";
    map.insert(make_pair(mapkey,20));
    
  4. программа выхода

В случае, если деструктор класса b1 печатает значение 'mapkey', возможно ли, что строка ключа карты будет уничтожена до класса b, так как она была создана после класса b1? и, следовательно, вызвать дамп ядра (так как '\0' будет не в конце массива)?

2 ответа

Стандарт гласит:

3.7.3

Динамическая продолжительность хранения [basic.stc.dynamic]

1 Объекты могут создаваться динамически во время выполнения программы (1.9) с использованием новых выражений (5.3.4) и уничтожаться с помощью deleteteexpressions (5.3.5).

Это означает, что в конце вашей программы любой объект, выделенный new что ваша программа не выпущена с delete все еще будет существовать, и не будет предпринято никаких попыток уничтожить его или его членов. Объект и все его участники будут "просочиться". Большинство операционных систем будут просто восстанавливать потерянную память после завершения процесса, но, опять же, они не будут C++- уничтожать представленные там объекты.

Пример:

#include <map>

struct A {
    std::map<int, int> m;
    int i;
};

int main() {
    A a1;  // cleaned up on scope exit
    A* a2 = new A;  // pointer lost on scope exit -- leak
}

Потому что мы не delete a2, ни класс, ни какой-либо из его членов не уничтожаются, вся память, используемая a2 и его членами, остается выделенной, пока операционная система не освободит память процессов.

Вы можете использовать RAII для управления этим, в самом деле, C++11 и более поздние версии предоставляют "умные указатели" для этого. По сути, умный указатель - это обертка объекта вокруг указателя; когда объект выходит из области видимости, он уничтожается, а деструктор [default] освобождает указатель:

#include <map>
#include <memory>

struct A {
    std::map<int, int> m;
    int i;
};

int main() {
    A a1;  // concreate instance: destructed on scope exit
    std::unique_ptr<A> a2 = std::make_unique<A>();
    // a2 is a concrete instance of a unique_ptr, so is destructed on scope exit
    // and it's destructor will delete the object pointed to for us.
}

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

В приведенном выше примере мы могли бы замкнуть unique_ptr определение к:

    auto a2 = std::make_unique<A>();

Когда программа заканчивается, элементы в куче уничтожаются по порядку?

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

Другие вопросы по тегам