2017-10-17 4 views
1

私はリンクリストを使用して、いくつかのメモリ管理(+ freepool + malloc)の実装に探していた、と私はそれらのほとんどには、各ノードは、このようなものであることが判明:次のポインタがノードの最上部の近くにあるのはなぜですか?

typedef struct node{ 
int usedSize; 
node* next; 
char mem[100]; 
} 

、その後free(ptr)でなければなりません。

free(void* ptr){ 
node* item = (node*)((char*)ptr - sizeof(node*) - sizeof(int)); 
\\some code to put the "item" back to the pool 
} 

私の質問はこれです: は、なぜ私たちは「ポインタ操作」を避けるために、構造体の先頭にchar mem[100];を置くべきではないのですか?

結果は次のとおりです。

typedef struct node{ 
char mem[100]; // moved to the beginning 
int usedSize; 
node* next; 
} 

、その後free(ptr)は簡単です:

free(void* ptr){ 
node* item = (node*)((char*)ptr); 
\\some code to put "item" back to the pool 
} 

感謝。

+1

すべての割り当てが正確に100バイトであれば正常に動作します。しかし、割り当てのサイズが異なる場合、どのように割り当てのサイズを見つけるのですか?割り当ての直前にサイズを置くと、単純になります。 – rici

+0

thatnks @riciしかし、私はそれを見つける必要はありません、私は ノードを使用してアクセスすることができます - > usedSize 私は何かが不足していますか? – mvk

+0

私が気づいていなかった答え(3)に感謝@jxh。 – mvk

答えて

1
  1. このポインタ操作は特に複雑ではありません。これは、コンパイル時定数によって減少します。コメント欄で述べたように、それが実際にすべきである:メモリ上にそのヘッダを配置

    node* item = (node*)((char*)ptr - offsetof(struct node, mem)); 
    
  2. メモリが、可撓性アレイメンバーによって表されることを可能にします。フレキシブルアレイメンバーは、構造の最後の位置のみを占有することができます。これはコメントでも指摘されています。

    typedef struct node { 
        int usedSize; 
        node* next; 
        char mem[]; 
    } node; 
    
  3. メモリのサイズが大きい場合、アレイ上にジャンプする可能性の高いフラッシュデータ・キャッシュ・ラインが簿記のデータをロードするであろう次のポインタに到達します。ただし、アレイから後ろに少しジャンプすると、既にキャッシュにロードされているデータにアクセスする可能性が高くなります。

関連する問題