C言語のmalloc地獄から解放するArena Allocator入門
Arena Allocators in C
C言語でメモリ管理を手動で行う際の課題を解決するArena Allocatorの実装ガイド。malloc/freeを個別に呼ぶ代わりに、同じライフタイムを持つデータを大きな1つの塊から割り当て、まとめて解放する。メモリリークを大幅に減らし、小さな確保と解放のオーバーヘッドを削減する。アラインメント処理やreallocラッパーを含むCコードと、文字列変換での使用例を紹介する。
メモリは無限の資源ではない。いつかコンピュータはメモリを使い果たし、プログラムはOSによって終了させられる(つまりクラッシュする)。
HNでの議論
11- teo_zero
void * ポインタに対するポインタ演算は定義されていないので注意してください。多くのコンパイラは許容していますが。"data" には char * を使った方がよいでしょう。
また、あなたのコードは data、used、alignment、size を加算する際にオーバーフローを起こしやすいです。
そして最後に、realloc 関数は new_size が old_size 以下なら何もしないように書き直せます。
- sweetjuly
> これはデータをアライメントするために使われます。どういうわけか、私たちのコンピュータは8バイトでアライメントされたデータを扱うのがずっと得意です。つまり、新しい割り当ての開始位置は8バイトの倍数でなければなりません。
自然なアライメントに合っていないポインタをキャストすることは、C言語では未定義動作です。単に非アライメントアクセスが遅くなるという問題ではなく、実際のプラットフォームと実際のコンパイラ実装では、プログラムがクラッシュしたり、予期しないデータにアクセスしたりする可能性もあります。
- unwind
提示されたコードには、もっと明らかな問題があります:
- 算術を行うマクロ(KiB、MIN など)が引数を括弧で囲んでいない。これは非常に危険です。
- コードは int と i32 が同じサイズであると仮定しています。
- malloc() の戻り値をキャストしないでください。これについてはググってください。
構造体を値で使っているのは素晴らしい設計だと思いました。
サイズ/アライメント周りの算術にオーバーフローのリスクがあることには同意しますが、64ビットの `usize` ならほぼ理論上の話でしょう。