web-dev-qa-db-ja.com

サイズゼロのmalloc

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

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

そして、それは私のマシンでsegfaultしません。 stdlib mallocおよびfreeの移植可能な動作ですか、それとも問題を探していますか?

編集:移植不可能と思われるのは、mallocによって返される値です。問題は、ptrの値ではなく、malloc(0)+自由な組み合わせについてです。

44
shodanex

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

  • free(NULL)は問題ありません。操作は行われません
  • free(address)は、アドレスがmalloc(または他のcallocなど)から受信された場合は問題ありません。
59
Key

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

要求されたスペースのサイズがゼロの場合、動作は実装定義です。ヌルポインターが返されるか、返されるポインターがオブジェクトへのアクセスに使用されないことを除いて、サイズがゼロ以外の値であるかのように動作します。 。

26
dfa

申し訳ありませんが、私はマニュアルページを読んでいるべきでした:

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

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

それは少なくともGNU libcに当てはまるようです

4
shodanex

C規格によると

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

3
rohittt

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

Malloc(0)を呼び出す動作は、実装に依存します。つまり、移植性はありません。 および未定義。

詳細については CFaq 質問へのリンク。

1
Aditya Sehgal

これは合法的な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

0
Jeffrey Walton