0

100000000 ノードに対して c++ 単独リンク リストの追加操作を実行します。ノードは毎回 0-10 の間の乱数を取得します。centos 64 ビットでは、ノードごとに 16 のサイズを取るため、1600000000 になりますが、タスク マネージャーによると 30.53mb と表示されます。ノードごとに。

node クラスには int データと node* が含まれています。

私の質問:

1.どうして違うの?

2.同じサイズを取得する特定の方法はありますか?

4

2 に答える 2

2

割り当てられるメモリのすべての「塊」にはオーバーヘッドがあり、通常、割り当てごとに 16 ~ 64 バイトです。

連続して 2 つのメモリ割り当てを行う場合、それらの間隔はどれくらい離れていますか。例えば

char *a = new char;
char *b = new char;

std::cout << b-a << std::endl;

delete a;
delete b;

(そうです、他の誰かが指摘する前に: 技術的には、このコードは未定義の動作です。しかし、x86-64 マシンでは、メモリはフラット メモリ モデルであるため、1 つのポインターから別のポインターを減算すると、2 つのオブジェクト間の距離が得られます。標準が「異なる割り当てのメモリ間の違い」を許可しない理由の 1 つは、アーキテクチャが 16 ビット OS/2 のようにセグメント化されたメモリを使用する可能性があるためです。各割り当てには独自のセグメントがあり、セグメントには独自のベースアドレスがありますが、ベースアドレスはユーザーモードアプリケーションによって認識されないため、この種のトリックを使用することは不可能です)

于 2013-09-02T09:18:45.933 に答える
0

リストのノードをどのように作成しますか? new? malloc? これらのメモリ割り当て関数はすべて、メモリ管理 (メモリの割り当て解除や再利用など) を可能にするために、余分なスペースを消費します。このオーバーヘッドは、多数の小さなメモリを割り当てた場合に最も顕著になります。

それが、あなたが見ているこのメモリオーバーヘッドの理由だと思います。

次のことを試すことができます。

  • 同じサイズの小さなピースのみを割り当てる場合は、固定配列 (または単に割り当てられた 1 回限りの配列) を使用してから、配列要素へのポインターをnextリスト ノードのメンバーとして使用してみてください。
  • tcmallocmallocなどの代替実装を試すこともできます。
于 2013-09-02T09:02:53.477 に答える