c++ - stl内存池中使用union节省空间的问题.
ringa_lee
ringa_lee 2017-04-17 14:23:54
0
2
728

最近在看sgi stl的内存池实现, 里面有如下的数据结构 :

typedef union obj {   
    union obj *free_list_link;   
    char client_data[1];    }obj;

据说可以节约空间, 但是不懂, 我个人感觉这种池应该是这样的, 也不知道对不对, 但是这为什么可以省内存呢? 难道说这个union省内存的地方在于它不需要一个指针来特意指向真正分配给用户的内存, 而是直接在这个union中分配, 也就是我图中这个下面的方块其实是由很多个union组成, 但是除了最后一个union其实是一个指针用来指向下一个方块的, 其它的其实都是用来直接分配给用户的, 不知道这样的理解对不对?

如图就是的左边就是我所理解的它的这种内存池的实现, 而右边就是那种使用结构体式的内存实现, 这样看得话确是每一个区块可以节约一个指针大小的空间, 但是我感觉其实用结构体也可以达到相同的效果啊, 并不会浪费内存啊... 比如如果我把右边的结构体中指向用户分配的内存那部分指针直接改成和左边一样, 直接用来作为用户所获得的区块, 那样两者就没有区别了...

ringa_lee
ringa_lee

ringa_lee

全員に返信(2)
伊谢尔伦

ご招待ありがとうございます

この文は正しいです: 実際にユーザーに割り当てられているメモリを具体的に指すポインタは必要ありませんが、この共用体に直接割り当てられます

同じ瞬間の 自由链表(free_list) は、次の機能のいずれか 1 つだけを持ちます: 1. 次の自由リンク リスト
2 を指すフリー リンク リスト ポインターとして。
以来ユーザーが を使用するための利用可能なメモリ として使用されます。 上記の目的は同時に発生できないため、
obj として定義され、unionfree_list_link はメモリを共有します。同じメモリを使用してメモリを節約します。 client_data

この文は間違っています:

実際には次のブロックを指すために使用されるポインターである最後の共用体を除いて、その他は実際にはユーザーに直接割り当てられるために使用されます

これはリンクされたリストであり、メモリ内のリンクされたリストの分布は乱雑で不連続であり、表示されている連続した領域ではないことに注意してください。

上で述べたように、
構造体は、ユーザーが使用するための割り当てられたメモリの一部として使用されるか、または obj が割り当てられる領域として空きリンク リスト に存在します。したがって、フリー リンク リストの各ブロックは、次のフリー リンク リスト ブロックを指します。これは次のように理解されます。 リーリー このフリー リスト ブロックがユーザーに割り当てられると、

フリー リスト

から削除され、フリー リスト ブロックとは見なされなくなります ( のセマンティクスにより、以降、ユーザーに割り当てられた通常のメモリ部分は、ユーザーが解放するまで空きリンク リストに再度追加されません) unionこの文は適切ではありません:

実際、同じ効果は実際の構造でも達成できます

メモリが割り当てられると、このメモリのポインタ (つまり、空きリンク リスト ブロック) ) は に戻り、その後、ポインタを保存するタスクがユーザーに引き渡されるのですが、なぜこれをメモリ コンフィギュレータに保持し続けると、さらに多くのポインタを保存するのにスペースが無駄になるのではないでしょうか?
無料リンク リストmalloc()/newには、未割り当てメモリのみが存在できます。 Hou Jie 訳の『STL Source Code Analysis』もお勧めです

いいねを押す +0
PHPzhong

基本的に問題はありませんが、ポインタのスペースを節約するためだけに、どのノードにも 2 つの状況があることがわかります。

  1. ノードがメモリを割り当てると、この共用体は実際に割り当てられたメモリへのポインタになります

  2. ノードはメモリを割り当てないため、この共用体は次のノードへのポインタです

構造体を使用することは可能です。たとえば、構造体にはポインターが 1 つだけありますが、ポインターの型は void * のみであり、毎回型を強制する必要があり、これは見苦しいです。 Union はよりエレガントです

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート