我对一些基本的字符串实现有点困惑。我一直在探源,了解内心的工作,学习新的东西。我不能完全理解记忆是如何管理的。
只是基本字符串实现的一些花絮
-
原始分配器用于字符类型
typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
-
。。。则当分配Rep被放置在所分配的缓冲器内时,计算CCD_
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
对象之后的下一个位置?
我对记忆对齐和铸造有一个基本的理解,但这似乎超出了我读过的任何东西
有人能帮我吗,或者给我指一些信息更丰富的读物?
您错过了新的位置。线路
_Rep *__p = new (__place) _Rep;
在CCD_ 7初始化一个新的CCD_。这个空间以前已经分配过了(这意味着一个新的放置不会自己分配,它实际上只是一个构造函数调用)。
C和C++中的指针算法告诉您,this + 1
是指向__size
0右侧sizeof(*this)
字节的指针。由于之前已经分配了(__capacity + 1) * sizeof(_CharT) + sizeof(_Rep)
字节,因此_Rep
对象之后的空间用于字符数据。布局是这样的:
| _Rep | (__capacity + 1) * _CharT |
分配器,如C的malloc
,返回指向字节的指针,而不是对象。因此,返回类型为char *
或void *
。
在C和C++标准的某个地方,有一个子句明确允许在char
和任何其他对象类型之间重新解释类型转换。这是因为C经常需要将对象视为字节数组(如写入磁盘或网络套接字时),并且需要将字节数组视为对象(如分配内存范围或从磁盘读取时)。
为了防止混叠和优化问题,不允许将相同的char *
强制转换为不同类型的对象,并且一旦将char *
强制转换为对象类型,就不允许通过写入字节来修改对象的值。