本日のテーマはmalloc
このmallocを使ったときにメモリが余分に確保される訳だけど、それはなぜ?って話。
結論から言うと未解決です。クソ記事です。
なので検索してきた方はごめんなさい。
でもまあまったく無駄という訳でもなかったのでとりあえず書くだけ書いてみる。
本題に入る前に予備知識とか。
まずCで型や変数のサイズを調べたい時はsizeofを使うけど、mallocで確保したサイズを知りたい時にsizeofは使えない。
正しくは以下のようにmalloc.hをインクルードしてmalloc_usable_sizeを使う。
[c] #include <stdio.h> #include <malloc.h> int main(void){ char s1[] = "12345"; char *s2; printf("sizeof(s1)=%d\n", sizeof(s1)); s2 = malloc(sizeof(s1)); //mallocで確保した分を見たい場合は正しくはこう printf("malloc_usable_size(s2)=%d\n", malloc_usable_size(s2)); return 0; } [/c]
次にアラインメントの話。
これは書くと長くなるので他に任せる。
ようするに高速化とかのために多少空白ができてしまっても決められた境界に値を置くようにするということ。
ここから本題。
じゃあ上記のプログラムを実行したらメモリはいくつ確保される訳!
自分の予想ではそのままの値、
つまりsizeof(s1)が\0を入れて6文字なので6バイト確保される。
またはアラインメントを意識して8バイトとかなのではないかと。
所が64bit環境で実行したところ、24という結果に。
かなり意味不明。確かに2の倍数ではある。8の倍数でもある。
けど多く取りすぎじゃない・・・!?
今度はs1を”0123456789012345678901234″、\0を入れて25文字にして実行したところ今度は40
どうやら24,40,56と増えていく模様。
いや16ずつ増えるのはわかったよ。多分アラインメントは16バイトなんだろう。
けど初めの24って何よ!8バイト余計なのは何なの!
ちなみに32bit環境で実行すると12,20,28,36と増える模様。
半分になってる。
気になったのでこういうのに詳しい後輩にアドバイス貰ったり、色々調べました。
結果として得られたことは以下の通り。
- 64bit環境で16Byteずつ、32bitで8Byteずつ増えるのは最も長いlong doubleを意識しているため。
- メモリにはChunkという機構があるけど、このChunkをmallocしたときにn個使う(確保する)
- だから16or8Byteずつ増えていく。
- (未解決)64bit環境で初めに24Byte確保する。16ByteはChunkだとして残りの余計な8ByteはChunkの管理情報
という具合。
結局2日くらいかけて調べたけれど完全解決に至らなくて悔しい。
その余計な8Byte(32bitだと4Byte)は本当に管理情報なのだろうか・・・。
この問題はまた暇なときかメモリ回りで困ったときに調べることにしよう。
以下、参考情報。
VA Linuxのmalloc解説。ここ結構凄いかもです。
http://www.valinux.co.jp/contents/tech/techlib/eos/malloc/malloc_001.html
追記(2010/06/28)
俺の友人の中で1,2を争う天才に助け舟を出してみて以下のことが分かったのでmemo。
- そもそもmalloc_usable_sizeは標準関数じゃない。
- 調べてもいまいち分からないし、malloc_usable_sizeが返す値は怪しい。
- mallocの実装によるけどK&R本なんかの例では線形リストっぽい管理の仕方をしている。
ああ、いまいち有益な情報になってない。・・・というか検索してもあんまり的確な情報が出てこないってのはどうでもいいことなのかもしれない。
・・・または単に俺の検索能力が低いだけか。
コメントを残す