Почему я не могу «уничтожить» вектор CRTP, который «принадлежит самому себе», но при этом может освободить свой адрес?C++

Программы на C++. Форум разработчиков
Ответить
Гость
 Почему я не могу «уничтожить» вектор CRTP, который «принадлежит самому себе», но при этом может освободить свой адрес?

Сообщение Гость »


Из яркого выступления Бьёрна Фаллера на заседании CPP 2023. => youtu.be/LKKmPAQFNgE

Речь идет о том, как можно заставить C++ терять память, не касаясь new или даже malloc.

struct V : вектор {}; авто v = V {}; v.emplace_back(); v.swap(v.front()); // представление v становится uint64_t[3]{ 0x0, 0x0, 0x0}, // поэтому выделение вектора теряется, поскольку в области видимости не остается ссылок. Интересно, смогу ли я уничтожить его вручную.

struct V : вектор {}; авто v = V {}; v.emplace_back(); v.emplace_back(); v.emplace_back(); v.emplace_back(); авто фронт = v.front(); v.swap(v.front()); использование распределителя = std::allocator; использование atraits = std::allocator_traits; авто а = front.get_allocator(); atraits::destroy(a, &front + 1); // Хорошо atraits::destroy(a, &front + 2); // Хорошо atraits::destroy(a, &front + 3); // Хорошо // atraits::destroy(a, &front); // ошибка SIGSEGV atraits::deallocate(a, &front, 4); // все еще кажется, что все в порядке? SIGSEGV возникает при попытке уничтожить объект V, которому принадлежит собственный адрес.

0x1796320 : 0x1796320 (alloc_begin_ptr) // Он владеет самим собой!!! 0x1796328: 0x1796380 (one_pass_content_end_ptr) 0x1796330: 0x1796380 (one_pass_alloc_end_ptr) 0x1796338: 0x0 (alloc_begin_ptr) 0x1796340: 0x0 (one_pass_content_end_ptr) 0x1796348: 0x0 (one_pass_alloc_end_ptr) 0x1796350: 0x0 (alloc_begin_ptr) 0x1796358: 0x0 (one_pass_content_end_ptr) 0x1796360: 0x0 (one_pass_alloc_end_ptr) 0x1796368: 0x0 (alloc_begin_ptr) 0x1796370: 0x0 (one_pass_content_end_ptr) 0x1796378: 0x0 (one_pass_alloc_end_ptr) Поэтому я попытался переместить его в стек. Кажется, работает нормально.

struct V : вектор {}; авто v = V {}; v.emplace_back(); v.emplace_back(); v.emplace_back(); v.emplace_back(); авто фронт = v.front(); v.swap(v.front()); auto v2 = std::move(фронт); Нет объектов, владеющих самим собой.

0x7ffc44d02b20: 0x927320 (alloc_begin_ptr) // v2 в стеке 0x7ffc44d02b28: 0x927380 (one_pass_content_end_ptr) 0x7ffc44d02b30: 0x927380 (one_pass_alloc_end_ptr) 0x927320: 0x0 (alloc_begin_ptr) 0x927328: 0x0 (one_pass_content_end_ptr) 0x927330: 0x0 (one_pass_alloc_end_ptr) 0x927338: 0x0 (alloc_begin_ptr) 0x927340: 0x0 (one_pass_content_end_ptr) 0x927348: 0x0 (one_pass_alloc_end_ptr) 0x927350: 0x0 (alloc_begin_ptr) 0x927358: 0x0 (one_pass_content_end_ptr) 0x927360: 0x0 (one_pass_alloc_end_ptr) 0x927368: 0x0 (alloc_begin_ptr) 0x927370: 0x0 (one_pass_content_end_ptr) 0x927378: 0x0 (one_pass_alloc_end_ptr) Почему allocator_traits::destroy() для vector, который сам себе владеет, запускает SIGSEGV?

// atraits::destroy(a, &front); // ошибка SIGSEGV 0x1796320 : 0x1796320 (alloc_begin_ptr) // Он владеет самим собой!!! 0x1796328: 0x1796380 (one_pass_content_end_ptr) 0x1796330: 0x1796380 (one_pass_alloc_end_ptr) [ПРЯМОЙ ЭФИР]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»