| 総合手引 | セクション 3 | English | Deutsch | オプション |
#include <stdlib.h>
通常 malloc() が返すメモリは、0 のバイトで初期化されては いない ことに注意してください。
calloc() 関数は、 number 個の、長さが size であるオブジェクトに空間を割り当てます。 この関数を呼び出した結果は、割り当てられたメモリが 0 のバイトに 明示的に初期化されていることを除けば、引数 "number * size" で malloc() を呼び出した結果と同じです。
realloc() 関数は、 ptr で参照される、以前に割り当てられたメモリのサイズを size バイトに変更します。 新しいサイズと古いサイズのうち、 小さい方のサイズまでのメモリ内容は変更されません。 新しいサイズの方が大きい場合、 新しく割り当てられた部分のメモリの値は未定義です。 要求されたメモリを割り当てることができなかった場合は NULL が返されますが、 ptr が参照するメモリは有効で変更されていません。 ptr が NULL である場合、 realloc() 関数は、指定したサイズの malloc() と同じ動きをします。
reallocf() 関数は、要求されたメモリを割り当てることができなかった場合に、 渡されたポインタを解放することを除けば、 realloc() 関数呼び出しと同じです。 これは FreeBSD に固有の API で、 realloc() の従来型のコーディングスタイルを用いると、 ライブラリの内部でメモリリークを引き起こすという 問題をなくすために設計されました。
free() 関数は、 ptr で参照される割り当て済みのメモリを 今後の割り当てのために使用できるようにします。 ptr が NULL である場合、何も実行されません。
/etc/malloc.conf というシンボリックリンクで参照されるファイルの「名称」、 環境変数 MALLOC_OPTIONS の値、 グローバル変数 malloc_options が指す文字列は、 この順序で 1 文字毎にフラグとして解釈されます。
ほとんどのフラグは 1 文字で、 大文字は動作が設定されたこと、つまりオンになっていることを表し、 小文字は動作が設定されていないこと、つまりオフになっていることを表します。
| A | すべての警告 (理解できないフラグが設定されているという警告を除く) を 致命的エラーにします。 この場合、プロセスは abort(3) を呼び出します。 |
| J | malloc(), realloc(), reallocf() に割り当てられる新規のメモリ、同様に free(), realloc(), reallocf() で返されるメモリの各バイトを 0xd0 に初期化します。 このオプションは "R" オプションもセットします。 これはデバッグ用のオプションで、パフォーマンスの低下に強い影響を与えます。 |
| H | 割り当て関数で使用されてないページに関するヒントをカーネルに与えます。 システムが過度にページングを行っている場合は、パフォーマンスが向上します。 このオプションは、デフォルトでオフになっています。 |
| R | 最初の割り当てが十分に大きい場合であっても、 realloc() 関数と reallocf() 関数が常にメモリの再割り当てをするようになります。 メモリを圧縮する場合の大きな助けとなります。 |
| U | すべてのオペレーションで、 ktrace(1) のための "utrace" エントリを生成します。 このオプションの詳細については、ソースを参照してください。 |
| V | 0 バイトを割り当てようとしたときに、 有効なポインタの代わりに NULL ポインタが返されるようになります (デフォルトの動作では、最小の割り当てを行って、そのポインタを返します)。 このオプションは System V との互換性のために提供されています。 このオプションは "X" オプションと適合しません。 |
| X |
割り当て関数でエラーを返す代わりに、
診断メッセージを stderr に 表示し、
(
abort(3)
を使って)
プログラムを core に落します。
このオプションは、コンパイル時に、
ソースコードに以下を組み込むようにして設定するべきです。
extern char *malloc_options; malloc_options = "X";
|
| Z | このオプションを設定すると、 "J" オプションと "R" オプションが 設定され、要求されたバイト列に 0 が出力されます。 これはデバッグ用のオプションで、パフォーマンスの低下に強い影響を与えます。 |
| < | キャッシュサイズを 2 分の 1 にします。 デフォルトのキャッシュサイズは 16 ページです。 このオプションは複数回指定できます。 |
| > | キャッシュサイズを 2 倍にします。 デフォルトのキャッシュサイズは 16 ページです。 このオプションは複数回指定できます。 |
"J" オプションと "Z" オプションは、テストとデバッグ用です。 これらのオプションを使用しているときに 動作が変わるアプリケーションには欠陥があります。
ln -s 'A<' /etc/malloc.conf
プログラムがこれらの関数の呼出し時に戻り値をチェックしないことを ソースで明示するには、
extern char *malloc_options; malloc_options = "X";
| MALLOC_OPTIONS | |
| 環境変数 MALLOC_OPTIONS を設定すると、この環境変数に含まれる文字は、 メモリ割り当て関数群のフラグとして解釈されます。 | |
realloc() 関数と reallocf() 関数は、成功した場合はもしかしたら ptr と同一の、割り当てられたメモリへのポインタを返します。 それ以外の場合は NULL ポインタを返します。 その場合でも ptr によって参照されるメモリは利用可能でそのまま残ります。 メモリの割り当てに失敗した場合は、 errno を ENOMEM に設定します。
free() 関数は値を返しません。
このアーキテクチャには、これまでは検出されなかったインタフェースの 細々とした違反が、実際に検出されるようになるという副作用があります。 このため、ずっと問題なく動いていたプログラムが、この割り当ての実装と リンクしたとたんに問題が続出することがあります。
最初にするべきこと、そしてもっとも重要なことは "A" オプションを設定することです。 このオプションを設定すると、 できるだけ処理を継続しようとする通常の方針をとるかわりに、 問題が発生したときに (可能であれば) コアダンプを強制的に取ります。
デバッガのサポートのために、 適切なオプションとシンボルでプログラムを再コンパイルするのが おそらく賢明です。
プログラムが、通常とは異なる結果を出したり、コアダンプしたり、 次のセクションで挙げるようなメッセージを出さずに 違った動作をし始めるような場合は、 プログラムが 0 のバイトで満たされている記憶領域に依存している場合だと 思われます。 "Z" オプションを設定して実行してみてください。 状況が好転した場合は、この診断が正しかったことになります。 これでもプログラムがおかしな動作をするようなら、 割り当てられた領域以外のメモリ、 大抵は割り当てられた領域の前方ではなく後方にアクセスするという問題だと 思われます。
あるいは、症状が容易に再現しない場合は、 "J" オプションを設定すると問題を起こす助けになるかもしれません。
本当に難しい状況では、カーネルで "U" オプションがサポートされている場合はそれを設定すると、 これらの関数のすべての呼出しの詳細なトレースが作成されます。
あいにく、この実装では、検出された問題に関する詳細は提供されません。 そのような情報を保存することで、パフォーマンスが悪影響を受けるためです。 パフォーマンスと引き換えにいっそうの健全さのチェックと詳細な診断を行い、 問題の検出と位置の特定に焦点を当てた数多くのメモリ割り当ての実装が、 インターネットで利用可能です。
以下では、出力される可能性があるエラーメッセージとその意味について 簡単に説明します。
| (ES): mumble mumble mumble | "EXTRA_SANITY" が定義された状態でメモリ割り当て関数がコンパイルされており、 詳細なエラーチェック中にエラーが検出されました。 詳細については、ソースコードを参照してください。 |
| mmap(2) failed, check limits | システムが危険な過負荷な状態であるか、プロセスの制限が正しく 指定されていないと思われます。 |
| freelist is destroyed | 内部の解放リストが壊れています。 |
| out of memory | "X" オプションが指定されていて、かつ、メモリの割り当てに失敗しました。 |
以下では、出力される可能性がある警告メッセージとその意味について 簡単に説明します。
| chunk/page is already free | すでに解放されているメモリを free() で解放しようとしました。 |
| junk pointer, ... | メモリ割り当て関数に与えられたポインタが、 認識されているメモリ境界の外側を指しています。 |
| malloc() has never been called | メモリが割り振られていないにも関わらず、解放しようとしたり、 再割り当てしようとしました。 |
| modified (chunk-/page-) pointer | free() か realloc() に渡されたポインタが書き換えられています。 |
| pointer to wrong page | realloc(), free() もしくは reallocf() が解放しようとしているポインタが、 正しいページを参照していません。 |
| recursive call | メモリ割り当て関数を再帰的に呼び出そうとしました。 これは許可されていません。 特にシグナルハンドラでは、メモリの割り当てをするべきではありません。 |
| unknown char in MALLOC_OPTIONS | 不明なオプションが指定されました。 "A" オプションを設定していても、この警告は単なる警告として扱われます。 |
reallocf(3) 関数は FreeBSD 3.0 ではじめて登場しました。
0 バイトを割り当てるように要求された場合に NULL ポインタを返すことは、愚かな問いかけに対する愚かな反応であると言えます。
| MALLOC (3) | August 27, 1996 |
| 総合手引 | セクション 3 | English | Deutsch | オプション |
このマニュアルページサービスについてのご意見は Ben Bullock にお知らせください。 Privacy policy.
| “ | "I liken starting one's computing career with Unix, say as an undergraduate, to being born in East Africa. It is intolerably hot, your body is covered with lice and flies, you are malnourished and you suffer from numerous curable diseases. But, as far as young East Africans can tell, this is simply the natural condition and they live within it. By the time they find out differently, it is too late. They already think that the writing of shell scripts is a natural act." | ” |
| — Ken Pier, Xerox PARC | ||