私の質問は非常に単純なものです。私たちが持っているとしましょう:
char* ptr = (char*) malloc(sizeof(char)*SIZE);
ptr+= SIZE/2;
free(ptr);
ポインターを解放するとどうなりますか? 未定義動作ですか?SIZE バッファのすべてを解放しますか、それとも残りの SIZE/2 のみを解放しますか? これを明確にしてくれてありがとう。
私の質問は非常に単純なものです。私たちが持っているとしましょう:
char* ptr = (char*) malloc(sizeof(char)*SIZE);
ptr+= SIZE/2;
free(ptr);
ポインターを解放するとどうなりますか? 未定義動作ですか?SIZE バッファのすべてを解放しますか、それとも残りの SIZE/2 のみを解放しますか? これを明確にしてくれてありがとう。
あなたのプログラムはおそらくクラッシュします: free() 操作は C では実際には非常に単純ですが、元の割り当てられたアドレスでしか機能しません。
一般的なメモリ アロケータは、次の疑似コードのように機能します。
したがって、 を呼び出すfree(ptr)
と、アロケータはポインタの 6 バイト前に移動して署名をチェックします。署名が見つからない場合、クラッシュします:)
への引数が、およびフレンドfree()
によって以前に割り当てられたポインターと一致しない場合、動作は未定義です。malloc()
のバージョンでセグメンテーション違反または失敗したアサーションが発生する可能性がありますlibc
。
malloc()
トピック外: の結果をCでキャストしない方がよいでしょう。
動作は定義されておらず、セグメンテーション違反が発生する可能性が最も高く、これは良いケースです。最悪の場合、プログラムのメモリが破損し、あらゆる種類の奇妙なバグや間違った出力が引き起こされます。
ほとんどの実装では、これにより何らかの致命的なエラーが発生するはずです。割り当てられたバッファの先頭のみを解放できます。
Windows (Visual Studio コンパイラを使用) で発生する典型的なエラーは、「有効なヒープ ポインターではありません」のようなものです。Linux では、上で phihag が述べたように、通常、セグメンテーション違反が発生します。どちらの場合も、通常はプログラムの実行を終了させるランタイム エラーです。
動作は未定義です。私はあなたがセグメンテーション違反を起こすと思います...それは私が私のシステムで試したときに得たものです.
free()
のようなメモリ アロケータ関数によって返されたアドレスを渡すことを呼び出し元に要求しますmalloc()
。それ以外の場合、未定義の動作が発生します。