Я немного запутался с некоторыми базовыми реализациями строк. Я изучал источник, чтобы понять внутреннюю работу и узнать что-то новое. Я не могу полностью понять, как память управляется.
Просто некоторые лакомые кусочки из базовой реализации строки
Необработанный распределитель для типа char
typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
... тогда при выделении Rep помещается в выделенный буфер __size
рассчитывается так же, чтобы соответствовать символам
size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
_Rep *__p = new (__place) _Rep;
Это то, как символьные данные выбираются из буфера _Rep
_CharT* _M_refdata() throw()
{
return reinterpret_cast<_CharT*>(this + 1);
}
Настройка персонажа - для одного типа пути
_M_assign(__p->_M_refdata(), __n, __c);
Что меня беспокоит, так это то, что необработанный распределитель имеет тип char, но выделенная память может содержать объект _Rep плюс символьные данные (которые не обязательно должны быть типом char)
Кроме того, почему (или, скорее, как) вызов _M_refdata
знает, где находится начало (или конец) символьных данных в буфере (то есть this+1
)
Редактировать: this+1
просто перемещает внутренний указатель на следующую позицию после объекта _Rep
?
У меня есть базовые представления о выравнивании и преобразовании памяти, но, похоже, это выходит за рамки всего, что я прочитал.
Кто-нибудь может помочь или указать мне более информативный материал для чтения?