我对某事感到困惑。
第一的:
int *ptr;
ptr = malloc(10 * sizeof(int));
这种在运行时获取动态(堆)内存,而不是像数组那样在编译时获取。
malloc()
NULL
如果没有内存可能会返回。
并且NULL
是#define
标准 C 库中的一个#define NULL ((void *)0)
因此,如果malloc
返回NULL
并在运行时执行,编译器将如何替换NULL
,void *0
我知道任何文本替换都发生在预编译阶段
我对某事感到困惑。
第一的:
int *ptr;
ptr = malloc(10 * sizeof(int));
这种在运行时获取动态(堆)内存,而不是像数组那样在编译时获取。
malloc()
NULL
如果没有内存可能会返回。
并且NULL
是#define
标准 C 库中的一个#define NULL ((void *)0)
因此,如果malloc
返回NULL
并在运行时执行,编译器将如何替换NULL
,void *0
我知道任何文本替换都发生在预编译阶段
不,你错了。想象一下这样的malloc
功能:
void *malloc(size_t n)
{
/* magic */
return NULL;
}
NULL
编译器在编译该翻译单元时替换,即编译标准库时,没有任何痕迹NULL
在预处理器阶段之后存活。在那之后,不管它的价值,malloc 只返回数字。
编译后所有的 NULL 都被 ((void *)0) 替换。如果没有内存,malloc 只会返回 ((void *)0)。
它返回 (void*)0 可以在源代码中的某处与 NULL 进行比较,例如:
int *ptr;
ptr = malloc(10 * sizeof(int));
if(ptr == NULL)
//do something
编译器替换NULL
if 表达式中的ptr
表达式((void *)0)
与 plain 相同0
,只是类型转换为 type void *
。这就是为什么您可以使用 egif (!myPointer)
来检查指针不是NULL
. 和palinNULL
一样,在 中定义0
什么并不重要,总是必须如此。NULL
malloc
NULL
0
在较旧的库中,并且仍然很常见,NULL
曾经被定义为 plain 0
,而在 C++ 中, plain0
通常用于代替NULL
.
回想一下void*
可以“携带”任何类型指针的事实。
例子:
void *h;
int *p, **pp;
h = p;
h = pp;
因此,如果 malloc 失败,它将返回 NULL,在 C 中定义为 (void*)0,正如其他答案所指出的那样。