実装に 16 バイトのアラインメントが必要な標準データ型がある場合 (long long
たとえば)、malloc
返されたブロックが正しくアラインされることは既に保証されています。C99 州のセクション 7.20.3The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object.
によって与えられたのとまったく同じアドレスを に戻す必要があります。例外なく。そうです、元のコピーを保持する必要があります。free
malloc
すでに 16 バイト アラインメントが必要な型がある場合は、上記の (1) を参照してください。
それを超えて、malloc
標準では保証されていませんが、実装が効率のために16バイトで整列されたアドレスを提供することに気付くかもしれません。必要に応じて、いつでも独自のアロケーターを実装できます。
私自身、その上に次の構造を使用するmalloc16
レイヤーを実装します。malloc
some padding for alignment (0-15 bytes)
size of padding (1 byte)
16-byte-aligned area
次に、malloc16()
関数を呼び出しmalloc
て、要求されたよりも 16 バイト大きいブロックを取得し、整列された領域がどこにあるべきかを判断し、その直前にパディングの長さを置き、整列された領域のアドレスを返します。
の場合free16
、指定されたアドレスの前のバイトを見てパディングの長さを取得し、そこから malloc されたブロックの実際のアドレスを計算し、それを に渡しfree
ます。
これはテストされていませんが、良いスタートになるはずです:
void *malloc16 (size_t s) {
unsigned char *p;
unsigned char *porig = malloc (s + 0x10); // allocate extra
if (porig == NULL) return NULL; // catch out of memory
p = (porig + 16) & (~0xf); // insert padding
*(p-1) = p - porig; // store padding size
return p;
}
void free16(void *p) {
unsigned char *porig = p; // work out original
porig = porig - *(porig-1); // by subtracting padding
free (porig); // then free that
}
の魔法の行はmalloc16
、p = (porig + 16) & (~0xf);
アドレスに 16 を追加し、下位 4 ビットを 0 に設定し、事実上、次に低いアラインメント ポイントに戻します (+16
これにより、maloc されたブロックの実際の開始点を過ぎていることが保証されます)。
さて、私は上記のコードが下品だとは言いません。対象のプラットフォームでテストして、機能するかどうかを確認する必要があります。その主な利点は、醜いビットを抽象化して、心配する必要がないことです。