push_back и исключительная безопасность - PullRequest
2 голосов
/ 25 апреля 2020

Я понимаю, что push_back может вызвать исключение bad_allo c, и если нет блока try catch, это не правда, что деструкторы вызываются. если какой-нибудь push_back-сгенерирует, и он не находится в блоке try catch, у меня будет утечка памяти? Это означает, что если я не хочу иметь утечку, я должен обернуть каждый push_back внутри попытки catch? Является ли это поведение слишком редким и дорогим для вектора, чтобы не перехватить исключение, освободить уже выделенную память и повторно выбросить исключение?

Ответы [ 2 ]

4 голосов
/ 25 апреля 2020

если нет блока try catch, это не правда, что деструкторы называются

Это определяется реализацией , происходит ли разматывание стека (которое вызывает деструкторы) в этом случае или нет.

если какой-либо push_back бросит, и он не находится внутри блока try catch, у меня будет утечка памяти?

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

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

Вместо того, чтобы помещать все содержимое main в try / catch, вы можете использовать std::set_terminate или что-то подобное.

1 голос
/ 25 апреля 2020

Теоретически, если push_back выбрасывает, память не выделяется самим контейнером.

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

v.push_back(new Obj{});

имеет это:

v.push_back(std::make_unique<Obj>())

Итак, если у вас есть некоторый верхний уровень обработки исключения std::bad_alloc (или любого std::exception), вы может восстановиться без утечек памяти, и вам не нужно переносить каждое выделение с помощью try / catch.


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

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

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