#c #boost-optional
#c #boost-необязательно
Вопрос:
Я пытаюсь разобраться в нескольких деталях, полученных из основного файла, в отношении boost:: необязательная переменная типа.
Переменная:
boost::optional<Cacher> cacher_;
Кадр # 5 из ядра:
(gdb) p this->cacher_
$1 = boost::optional
Строка, выполняемая в этом фрейме, является:
cacher_ = boost::none;
В результате несколько кадров, приведших к сбою, указывают на код библиотеки boost:
#1 0x000000000152f96c in destroy_impl (this=0x32557590) at /opt/include/boost/optional/optional.hpp:479
#2 destroy (this=0x32557590) at /opt/include/boost/optional/optional.hpp:439
#3 assign (this=0x32557590) at /opt/include/boost/optional/optional.hpp:313
#4 operator= (none_=NULL, this=0x32557590) at /opt/include/boost/optional/optional.hpp:615
Фрейм # 0 — это место, где Cacher
вызывается деструктор, а сбой происходит из-за того, что память, удерживаемая объектом, уже освобождена.
Мой вопрос:
boost::optional
Указывает ли, что память, удерживаемая,cacher_
действительна?- В результате присвоения
boost::none
cacher_
будет ли объект уничтожен?
Приносим извинения, если деталей для диагностики проблемы недостаточно. Я постараюсь предоставить дополнительную информацию на основе ответов.
Спасибо!
Ответ №1:
Да, boost::optional
отслеживает, содержит ли он допустимый объект. Это можно проверить с помощью operator bool()
или is_initialized()
.
Если вы назначите boost::none
(или вызовете .reset()
), он должным образом уничтожит объект, который он содержит, если таковой имеется.
То же самое справедливо и для std::optional
(за исключением boost::none
присваивания, насколько мне известно).
Комментарии:
1.
(gdb) frame 3 #3 assign (this=0x32557590) at /opt/ include/boost/optional/optional.hpp:313 313 void assign ( none_t ) { destroy(); } (gdb) p *this $9 = {<boost::optional_detail::optional_tag> = {<No data fields>}, m_initialized = false, m_storage = {dummy_ = { data = “………………………………….", aligner_ = {<No data fields>}}}}
m_initialized = false
Указывает ли, что объект недействителен?2. Я не думаю, что valid — это правильный термин. Необязательный тип пуст, в нем нет объекта. Вроде как пустой
unique_ptr
(необязательный очень похож на интеллектуальный указатель, но мы используем его для ясности).3. ОК. В данном случае, что мы пытаемся уничтожить, когда объекта нет? В любом случае, правильно ли назначать
boost::none
без проверки тогоcacher_
, инициализирован он или нет?4. Если объекта нет, ничто не должно быть уничтожено. Безопасно назначать
boost::none
такому необязательному, но он должен оставить его в идентичном состоянии (например, присвоениеnullptr
уже пустомуunique_ptr
)5. Разве деструктор не вызывается для объекта? Чего мне не хватает в данном случае?