C言語では、動的メモリ管理のためにstdlib.hライブラリの関数が使用されます:
malloc(size_t size) — 指定されたサイズのメモリブロックを割り当てます。メモリは初期化されていません。calloc(size_t nmemb, size_t size) — nmemb要素の指定されたサイズの配列用メモリブロックを割り当て、ゼロで初期化します。realloc(void *ptr, size_t size) — 以前に割り当てたメモリブロックのサイズを変更します。free(void *ptr) — 以前に割り当てたブロックを解放します。使用例:
int *arr = (int *)malloc(10 * sizeof(int)); if (arr == NULL) { // メモリ割当てエラーの処理 } // ... arrでの作業 ... free(arr);
常にメモリ割当の結果がNULLでないか確認し、メモリリークを避けるためにfreeを呼び出すことを忘れないことが重要です。
次のコードの結果は何ですか?
int *arr = malloc(sizeof(int) * 5); free(arr); free(arr);
答え: 同じメモリ領域に対してfreeを再度呼び出すと未定義の動作(undefined behavior)を引き起こします。同じポインタを解放するのは一度だけ可能です。
物語
テスト自動化システムのプロジェクトで定期的にクラッシュが発生しました。原因はシステムサイクルで、各循環後に
mallocで割り当てたメモリを解放するのを忘れていました。その結果、長時間のテストでシステムがすべてのRAMを消費し、フリーズしました。
物語
動的配列の実装が
reallocを使用し、戻り値の結果を確認しませんでした。失敗した場合(reallocがNULLを返した場合)、古いメモリへのポインタが失われ、メモリリークが発生しました。メモリを操作しようとするとセグメンテーションフォルトが発生しました。
物語
開発者は、メモリが
freeで同じ参照で二度解放されていた古いCモジュールの統合を任されました。ほとんどのオペレーティングシステムではエラーは発生しませんでしたが、新しいプラットフォームではアプリケーションがクラッシュし、原因は長い時間が経ってから発見されました:ダブルフリー。