LINUX.ORG.RU

C++ динамическое выделение памяти и unique_ptr

 ,


0

1

Суть:

class foo
{
public:
	foo(size_t sz1, size_t sz2) :
			sz1_(sz1),
			sz2_(sz2)
	{
		try
                {
                	data1.resize(sz1_);
			// fill data1

			data2.reserve(sz2_);
			// data2 will be filled later
                }
                catch (std::bad_alloc const&) {
                	std::cout << "Memory is over! :(" << std::endl;
                }
	}	    

	size_t sz1_;
	size_t sz2_;

	std::vector<char> data1;
	std::vector<int> data2;
};

unique_ptr<foo> a(new foo(5,10));	
unique_ptr<foo> b(new foo(8,31));

Хочу гарантировать отсутсвие утечек в случае если память закончилась и exception safety. В случае, если вектор бросает исключение создание объекта прекращается. Чему в этом случае будет равно а? nullptr? Всё ли верно?

Чему в этом случае будет равно а? nullptr?

С чего бы? В a будет храниться указатель на успешно созданный foo, при создании которого либо data1.resize либо data2.reserve бросил исключение.

Всё ли верно?

Мне кажется ты хотел не этого.

slovazap ★★★★★
()
Ответ на: комментарий от Deleted

Получается единственный способ узнать, что создание unique_ptr зафэйлилось - пробрасывать исключение дальше из конструктора?

try
{
	unique_ptr<foo> a(new foo(5,10));
}
catch(...)
{}
spectral1989
() автор топика
Ответ на: комментарий от slovazap

Мне кажется ты хотел не этого.

Верно) я хотел отследить, что неудача на пути конструирования объекта возникла

spectral1989
() автор топика
Ответ на: комментарий от spectral1989

что создание unique_ptr зафэйлилось

Ты наверное имел в виду создание foo. Создание unique_ptr здесь не может зафейлиться. Да, правильно проверять снаружи. Скорее всего ещё правильнее вообще не проверять.

slovazap ★★★★★
()
Ответ на: комментарий от spectral1989

Я код не читал особо и напейсал тебе неверно. У тебя всё создастся, но вектора(в случае фейла) будут пустые. А создание unique_ptr из указателя никогда не фейлиться

Deleted
()
Ответ на: комментарий от spectral1989

пробрасывать исключение дальше из конструктора?

Зачем его пробрасывать, оно само пробросится если ты уберёшь try/catch в конструкторе.

try { unique_ptr<foo> a(new foo(5,10)); }

Имей в виду что здесь у тебя foo будет уничтожен в конце блока try.

slovazap ★★★★★
()
Последнее исправление: slovazap (всего исправлений: 2)
Ответ на: комментарий от slovazap

В a будет храниться указатель на успешно созданный foo

Сомневаюсь. Скорее всего, там ничего определённого, потому что до конструктора unique_ptr дело не дойдёт: брошенное исключение будет разворачивать стек, и пропустит фрейм, где a было бы инициализировано. Если a — переменная модуля (или как там глобальные называются), то в памяти под объект при запуске будут нули. Там они и останутся.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Сомневаюсь. Скорее всего, там ничего определённого

Сомнениям и гаданиям в программировании места нет. Проходите, пожалуйста, мимо, если точно не знаете как работает простейший код.

Объект будет успешно сконструирован, никакого разворачивания не будет потому что исключение перехвачено и обработано в том же фрейме.

slovazap ★★★★★
()
Последнее исправление: slovazap (всего исправлений: 1)
Ответ на: комментарий от Deleted

У тебя всё создастся, но вектора(в случае фейла) будут пустые. А создание unique_ptr из указателя никогда не фейлиться

Спасибо, осознал

spectral1989
() автор топика
Ответ на: комментарий от slovazap

Зачем его пробрасывать, оно само пробросится если ты уберёшь try/catch в конструкторе.

Осознал, спасибо!

spectral1989
() автор топика

std::make_unique

anonymous
()
Ответ на: комментарий от slovazap

Объект будет успешно сконструирован, никакого разворачивания не будет потому что исключение перехвачено и обработано в том же фрейме.

Утверждаешь, что конструктор std::vector не бросает?

i-rinat ★★★★★
()
Ответ на: комментарий от slovazap

Какой конструктор какого std::vector

std::vector<T>::vector()

и какое отношение это имеет к обсуждаемому коду?

Прочитай обсуждаемый код.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Обсуждаемый код про исключения из resize и reserve. Какое к этому отношение имеет конструктор по умолчанию?

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

Обсуждаемый код про исключения из resize и reserve.

Где это написано? Прочитай ОП снова. Там нет вопроса про resize и reserve.

Зато там в тегах есть C++11, а в нём гарантий noexcept на std::vector<T>::vector() ещё не было.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

не бросает?

Формально, начиная с c++17

noexcept(noexcept(Allocator()))
std::allocator<T>::allocator() noexcept

А фактически, всегда так было(стандарт в некоторых местах описывает вещи неполно)

Deleted
()
Ответ на: комментарий от i-rinat

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

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

Вот сейчас вьёшься ты, и я это за тобой не первый раз замечаю.

У тебя не хватает смелости ошибку свою признать. Уже который раз.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Ну и опять кончилось тем что ты опустился до «сам дурак», не ответив ни на одно замечание по существу. Продолжай в том же духе.

slovazap ★★★★★
()
Ответ на: комментарий от Deleted

А фактически, всегда так было

Понятное дело, там просто не нужно ничего аллоцировать. Но это же Си++. Исключение может прилететь откуда угодно. Если заботишься об exception safety, нужно это делать тщательно.

i-rinat ★★★★★
()
Ответ на: комментарий от slovazap

Не было замечаний по существу. Ты пытаешься выкрутиться просто, вот и всё.

Можешь привести цитату из ОП про то, что вопрос именно про resize? Нет, не можешь. И пытаешься теперь извиваться.

Ну и опять кончилось тем что ты опустился до «сам дурак»

Где тут «сам дурак»? Ты действительно заносчив, и не желаешь признавать ошибку, даже если она очевидна.

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от i-rinat

Ты удалил свое сообщение, подумал и нашел к чему еще придраться. Для чего даже в теги залез. При том что ТСа явно волновал именно resize, который он заключил в try/catch. Это не «выкручиваться»?

А по сути,

Понятное дело, там просто не нужно ничего аллоцировать

как минимум в MSVS дефолтный конструктор аллоцирует (или раньше это делал).

anonymous
()
Ответ на: комментарий от anonymous

Ты удалил свое сообщение

Это правда.

подумал и нашел к чему еще придраться

Это неправда. В удалённом сообщении то же самое, но более размыто. Решил написать прямо, потому что «специалист» намёков не понимает, он слишком горд для этого.

Для чего даже в теги залез.

Нет.

При том что ТСа явно волновал именно resize, который он заключил в try/catch. Это не «выкручиваться»?

Давайте у ТС'а спросим, рад ли он, что половину истории ему не рассказали.

i-rinat ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.