52

非常に単純な質問ですが、次のプログラムを作成しました。

#include <stdlib.h>
int main(int argc, char ** argv)
{
    void * ptr;
    ptr = malloc(0);
    free(ptr);
}

また、私のマシンではセグメンテーション違反はありません。stdlib malloc と free の移植可能な動作ですか、それともトラブルを探していますか?

編集: 移植性がないように見えるのは、malloc によって返される値です。問題は、ptr の値ではなく、malloc(0) + フリーの組み合わせに関するものです。

4

7 に答える 7

69

動作は実装定義であり、NULL ポインターまたはアドレスのいずれかを受け取ります。ただし、受信したポインターに対して free を呼び出しても、次の理由から問題は発生しません。

  • free(NULL) は問題ありません。操作は行われません
  • アドレスが malloc (または calloc などの他のもの) から受信された場合、free(address) は問題ありません。
于 2009-07-02T08:33:04.047 に答える
34

NULL を返すことも、逆参照できない非 NULL ポインターを返すこともできます。どちらの方法も、標準 (7.20.3) によって認可されています。

要求されたスペースのサイズがゼロの場合、動作は実装定義です。null ポインターが返されるか、サイズがゼロ以外の値であるかのように動作します。ただし、返されたポインターはオブジェクトへのアクセスには使用されません。 .

于 2009-07-02T08:30:35.923 に答える
4

お手数をおかけして申し訳ありません。マニュアルページを読むべきでした:

malloc()は size バイトを割り当て、割り当てられたメモリへのポインタを返します。メモリはクリアされません。サイズが 0 の場合、malloc() は NULL を返すか、後で free() に正常に渡すことができる一意のポインター値を返します。

free() は、ptr が指すメモリー空間を解放します。これは、以前の malloc()、calloc()、または realloc() への呼び出しによって返されたものでなければなりません。それ以外の場合、または free(ptr) が以前に呼び出された場合、未定義の動作が発生します。ptr が NULL の場合、何も実行されません。

少なくともgnu libcについては本当のようです

于 2009-07-02T08:31:00.133 に答える
3

c標準によると

7.20.3 要求されたスペースのサイズがゼロの場合、動作は実装で定義されます。null ポインターが返されるか、サイズがゼロ以外の値であるかのように動作します。ただし、返されたポインターはアクセスに使用されません。オブジェクト。

于 2009-07-02T08:31:37.903 に答える
0

それは合法的なC/C ++かもしれませんが、それはより大きな問題を示しています。私は一般的にそれを「ポインターの傾斜」と呼んでいます。

「malloc(0)またはcalloc(0)の結果について推測しないでください」、https: //www.securecoding.cert.org/confluence/display/seccode/VOID+MEMxx-A.+Do+not+を参照してください。 make + assumptions + about + the + result + of + malloc%280%29 + or + calloc%280%29

于 2010-08-24T16:24:16.293 に答える
0

libt と Pax のコメントを考慮して更新:

malloc(0) の呼び出しの動作は実装に依存します。つまり、移植性がなく未定義です。

詳細については、 CFaqの質問へのリンクを参照してください。

于 2009-07-02T08:31:13.240 に答える
-3

私の経験では、malloc (0) が解放可能なポインタを返すことを見てきました。ただし、これにより、後の malloc() ステートメントで SIGSEGV が発生します。そして、これは非常にランダムでした。

割り当てられるサイズがゼロの場合はmallocを呼び出さないというチェックを追加したところ、これを取り除きました。

したがって、サイズ 0 にはメモリを割り当てないことをお勧めします。

-アシュトッシュ

于 2013-06-04T06:34:20.827 に答える