簡単な質問
malloc を事前に呼び出さずに free() 関数を使用できますか??
エイ。
void someFunc( void )
{
char str[6] = {"Hello"};
//some processing here ....
free(str);
}
コンパイルエラーは発生しませんが、これは機能しますか、それともまったく正しいですか?
ありがとうございました、
これはまったく正しくありません。
char str[6]
。free()は、割り当てられたブロックに付加されたデータを使用してヒープを管理します。示されたメモリがmalloc()やcalloc()などのヒープ割り当て関数によって割り当てられていない場合、ブロックの前にあるデータはヒープ管理データとして無意味になります。
一部のライブラリは、無効なヒープデータを検出し、ランタイムエラーを生成します。それ以外の場合、動作は定義されていません。多くの場合、このようなエラーの結果は、後でさらにメモリを割り当てようとするまで気付かれません。これにより、このようなエラーのデバッグが非常に困難になる可能性があります。
構文エラーではなく、コンパイル時に検出できないため、コンパイラエラーは発生しません。コンパイラーは、ライブラリー関数のセマンティクスについての知識を持っていません。それが知っているのは、malloc()がvoid *を返し、free()がvoid*を受け入れることだけです。メモリは定義上実行時に割り当てられるため、ポインタが動的に割り当てられたブロックを参照しているかどうかをコンパイル時に知る方法はありません。また、ポインタは実行時に任意のメモリタイプを指すように変更することも、エイリアスを作成することもできます。別のポインタにコピーしてから、2番目のポインタを介して解放します。エラーメッセージが表示される場合は、多くのコンパイラが必要です。ただし、一部の静的分析ツールは、そのようなエラーが発生する可能性がある場合に警告できる場合があり、valgrindなどの動的分析ツールは、テスト中に実際に発生した場合にエラーを検出する場合があります。
malloc されていない変数で free を使用すると、通常は Segfault が発生します。例:
#include <stdlib.h>
int main()
{
char str[6] = {"Hello"};
free(str);
}
$ gcc test.c -o テスト
$ ./テスト
セグメンテーション違反
このfree(3)
関数はvoid *
パラメーターを受け取るため、コンパイル時にエラーが発生することなく、任意の種類のポインターを渡すことができます。malloc(3)
しかし、ポインターが最初に によって返されたものではなく、以前に に返されたことがない場合、悪いことが起こりますfree(3)
。