Исключение в конструкторе и утечки памяти - PullRequest
1 голос
/ 28 марта 2019

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

class A
{
    int *x;
public:
    A () { x = new int; throw 0;}
    ~A () { delete x; }
};

Я хочу создать объекты такого класса динамически.Как мне сделать это, чтобы предотвратить утечки памяти?Я пытался создать объекты в блоке try и удалить в блоке catch, но адрес-дезинфицирующее средство сообщило SEGV on unknown address.

int main()
{
    A *a;
    try { a = new A; }
    catch(int) { delete a; } // AddressSanitizer: SEGV on unknown address
}

Без удаления имеющегося у нас объекта (очевидно) утечка памяти и средство для очистки утечки сообщает, что.

int main()
{
    A *a;
    try { a = new A; }
    catch(int) {} // LeakSanitizer: detected memory leaks
}

Однако без try - catch оба дезинфицирующих средства молчат.Мне интересно, есть ли еще утечка памяти и, если да, как ее исправить?

int main()
{
    A *a;
    a = new A; // terminate called after throwing an instance of 'int'
}

UPD: Да, я знаю об общих указателях.Мой вопрос в основном о последнем случае (без обработки исключения).Почему дезинфицирующие средства молчат?Это просто утечка или дезинфицирующее средство?

1 Ответ

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

Недопустима следующая часть кода:

int main()
{
    A *a;
    try { a = new A; }
    catch(int) { delete a; } // AddressSanitizer: SEGV on unknown address
}

Если при выполнении new A выдается исключение, то все, что А удалось построить, до исключения являетсяподорванный.Кроме того, память a освобождается автоматически.

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

Самый безопасный способ обойти утечку - использовать std::unique_ptr.

class A
{
    std::unique_ptr<int> x;
public:
    A (): x(std::make_unique<int>()} { throw 0;}
    A(A&&) = default;
    A& operator=(A&&) = default;
    A(const A &); // do something smart here
    A& operator=(const A &); // do something smart here
    ~A () { }
};

С unique_ptr чем-либо, сконструированным до того, как исключение будет автоматически освобождено.

...