我对一些基本的字符串实现有点困惑。我一直在寻找内心的工作和学习新事物。我无法完全掌握如何管理内存。
来自基本字符串实现的一些花絮
原始分配器用于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
对象后面的下一个位置吗?
我对内存对齐和转换有基本的了解,但这似乎超出了我所读过的内容。
有人可以提供帮助,还是给我提供更多信息丰富的阅读材料?
答案 0 :(得分:5)
您错过了新的展示位置。这条线
_Rep *__p = new (__place) _Rep;
在_Rep
初始化新的__place
- 对象。之前已经分配了这个空间(意味着一个placement-new本身没有分配,它实际上只是一个构造函数调用)。
C和C ++中的指针算术告诉您,this + 1
是指向sizeof(*this)
右侧this
个字节的指针。由于之前已经分配了(__capacity + 1) * sizeof(_CharT) + sizeof(_Rep)
个字节,因此_Rep
对象之后的空格用于字符数据。布局就像这样:
| _Rep | (__capacity + 1) * _CharT |
答案 1 :(得分:0)
分配器,如C的malloc
,返回指向字节的指针,而不是对象。因此,返回类型为char *
或void *
。
在C和C ++标准的某处,有一个子句明确允许在char
和任何其他对象类型之间重新解释。这是因为C经常需要将对象视为字节数组(如写入磁盘或网络套接字时),并且需要将字节数组视为对象(例如,在分配一系列内存或从磁盘读取时)。
为了防止别名和优化问题,您 允许将相同的char *
投射到不同类型的对象上,并且一旦您将char *
投放到{{1}}对象类型,不允许通过写入字节来修改对象的值。