#c #memory #allocator
Вопрос:
Я не хочу иметь возможность уничтожить какой-либо объект, не потеряв память:
from: `-------- -------- --------` | item 1 | item 2 | item 3 | `-------- -------- --------` to: `-------- -------- --------` | item 1 | empty | item 3 | `-------- -------- --------`
Используется std::vectorlt;Tgt;::erase
то, что ближе всего к нему, но это не позволяет мне получить доступ к старой «памяти».:
`-------- --------` | item 1 | item 3 | `-------- --------`
Я пытался использовать std::allocator_traitslt;Tgt;
, но я не понял, как использовать его для компиляции:
using allocator = std::allocator_traitslt;typegt;; using alloc_type = std::allocator_traitslt;typegt;::allocator_type; class MyClass { public: MyClass(int i) : m_i(i) {} ~MyClass() = default; private: int m_i; }; int main() { std::vectorlt;MyClass, allocatorgt; vec; vec.emplace_back(0); // destroy the object but don't rearrange allocator::destroy(alloc_type, std::addressof(vec[0])); }
Этот код не компилируется
Комментарии:
1.
std::vector
это смежный контейнер, в нем не может быть пустых отверстий. Рассмотрите возможность использованияstd::vectorlt;std::optionallt;MyClassgt;gt;
, чтобы разрешить обнуление элементов для представления «дыр» или отсутствующих элементов.2. Почему вам нужно это делать? Это выглядит как плохая проблема. Объясните, чего вы пытаетесь достичь, потому что, скорее всего, существует лучшее/более чистое решение, чем то, что вы пытаетесь сделать.
3. Когда программа не компилируется, первым шагом является чтение сообщения об ошибке.
Ответ №1:
Возможно, вы не уничтожили объекты в векторе. Вектор в конечном итоге уничтожит все элементы, и если таковые уже уничтожены, то поведение будет неопределенным.
Вместо вектора MyClass
, вы можете использовать вектор std::aligned_storage
и самостоятельно обрабатывать строительство и уничтожение MyClass
объектов в хранилище. Но я не рекомендую этого делать, потому что это может быть довольно сложно, а тривиальные ошибки приведут к неопределенному поведению.
Если ваша цель-представить состояние «без значения», то для этой цели в стандартной библиотеке есть оболочка шаблона: std::optional
. Т. е. вы могли бы использовать std::vectorlt;std::optionallt;MyClassgt;gt;
.