3

我对一些基本的字符串实现有点困惑。我一直在通过源代码了解内部工作并学习新事物。我无法完全掌握内存是如何管理的。

只是一些基本字符串实现的花絮

  • 原始分配器用于 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对象之后的下一个位置?

我对内存对齐和强制转换有基本的了解,但这似乎超出了我所读过的任何内容。

任何人都可以提供帮助,或者向我指出更多信息丰富的阅读材料吗?

4

2 回答 2

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  |
于 2012-01-10T20:53:31.777 回答
0

分配器,像 C 一样malloc,返回指向字节的指针,而不是对象。因此,返回类型是char *or void *

在 C 和 C++ 标准中的某处,有一个子句明确允许重新解释char与任何其他对象类型之间的转换。这是因为 C 经常需要将对象视为字节数组(如写入磁盘或网络套接字时),并且需要将字节数组视为对象(如分配一定范围的内存或从磁盘读取时)。

为了防止出现别名和优化问题,不允许将相同类型的对象强制转换为不同类型的对象,并且一旦将 a 强制转换为对象类型,就不能通过写入字节来修改对象的值。char *char *

于 2012-01-10T20:52:25.543 回答