0

このステートメントに遭遇したとき、私はposix_memalign関数についての説明のために glibc マニュアルを調べていました:

GNU システムで malloc または realloc によって返されるブロックのアドレスは、常に 8 の倍数 (または 64 ビット システムでは 16)です。それより高い 2 の累乗の倍数のアドレスを持つブロックが必要な場合は、memalign、posix_memalign、または valloc を使用します。

int データ メンバーだけを含む単純な構造を考えると、次のようになります。

struct Mystruct
{
 int member;
};

次に、Mystruct が 4 バイト アラインされている必要があることがわかります。しかし、64 ビット アーキテクチャの libc マニュアルによると、このような構造体にメモリを動的に割り当てると、16 バイト アラインメントのアドレスに割り当てられたメモリが返されます。

私が間違っている場合は修正してください。私には、コンパイラがグローバル/静的/自動変数 (データ、bss、スタック) に対してのみ構造の自然な配置を使用しているように思えます。しかし一方で、同じ構造をヒープ メモリに割り当てるには、malloc 呼び出しで事前定義されたアラインメント (32 ビット アーキテクチャでは 8、64 ビット アーキテクチャでは 16) を使用します。

4

1 に答える 1

0

覚えておく価値のあることの 1 つは、malloc() は魔法のようなものではなく、単なる関数であるということです。同様に、ヒープは、コンパイラがその内容に触れないことを約束する単なるメモリの集まりです。ものを静的に (スタック上または data/bss 内に) 割り当てることは、コンパイラー行うことなので、指定されたアライメントに合わせてそれらをアライメントできます。malloc() (および関連する関数) はヒープを管理する関数ですが、実行時に呼び出されます。コンパイラは、それが関数であることを除いて、malloc() について何も知りません。また、malloc() は、要求している量を除いて、割り当てるように要求しているメモリについて何も知りません。ほとんどの一般的な用途では、通常は 16 ビット アラインメントで問題ないため、malloc() はこのアラインメントが安全であることを保証します。

PS: 楽しい (そして目を見張る) 演習は、独自の malloc() 実装を作成することです。

于 2012-06-26T00:19:14.917 に答える