malloc(3) でハマッタのでメモッタ。
どもです。
オートミールを食べ始めたせいか,便通がよろしいようで,快便ですたいっ!
malloc(3) ではまる。
メモリ関連のコードを書いていて,テストを書いて,テストでこけた。
printf で原因を調べると,どうやらアラインメントの問題でこけているようだった。
あるサイズの倍数のアドレスで割り当ててるはずが,そうなってない。
自分で書いたコードには問題が見つからず。
というわけで,man malloc してみた。
一部抜粋。
For calloc() and malloc(), return a pointer to the allocated memory, which is suitably aligned for any kind of variable.
どうやら,calloc(), malloc() ともに,
いい具合にアラインメントを調整してくれるようだ。
何がいい具合か知らんが。
ほいで,ググってみると以下のページを見つけた。
http://www.gnu.org/s/libc/manual/html_node/Aligned-Memory-Blocks.html
最初の方を引用。
The address of a block returned by malloc or realloc in the GNU system is always a multiple of eight (or sixteen on 64-bit systems). If you need a block whose address is a multiple of a higher power of two than that, use memalign, posix_memalign, or valloc. memalign is declared in malloc.h and posix_memalign is declared in stdlib.h.
GNU システム上の,malloc, realloc が返すアドレスは常に8の倍数。
気にいらん場合は,memalign, posix_memalign, valloc() などを使えとのこと。
わかったにょろよ。
man posix_memalign してみると,memalign, valloc() は obsolete のようだ。
まとめると・・・。
struct foo *ptr = malloc(sizeof(*ptr)); // ↑が気に入らなくて,例えば,16の倍数でアラインしてもらいたい場合は, int ret = posix_memalign(&ptr, 16, sizeof(*ptr)); if (ret != 0) { // エラー ... }
ってな感じになる。
ちなみに,posix_memalign に渡す第2引数は,2の累乗じゃないとこけるとのこと。
変更してみて,テストを実行したら,ばっちぐーでした。
アラインメントなんて気にしたことなかったから,原因を探すのに
苦労しました。でもいい勉強になったと思うにょろ。