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);
    }
    
  • キャラクターの設定 - 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-object を初期化し__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 *void *です。

C および C++ 標準のどこかに、charと他のオブジェクト型の間のキャストの再解釈を明示的に許可する句があります。これは、C がオブジェクトを (ディスクまたはネットワーク ソケットに書き込むときのように) バイト配列として扱う必要があることが多く、バイト配列をオブジェクトとして扱う必要があるためです (メモリ範囲の割り当てやディスクからの読み取りのときなど)。

エイリアシングと最適化の問題から保護するために、同じものを異なる型のオブジェクトにキャストすることは許可されていませんchar *。また、一度char *オブジェクト型にキャストした後は、バイトに書き込むことによってオブジェクトの値を変更することはできません。

于 2012-01-10T20:52:25.543 に答える