其他人已经讨论过 <malloc.h> 和 <stdlib.h> 之间的区别
至于两者都不包含时的警告,那是 C 函数如何工作的定义。没有原型的函数(当您没有声明自己的原型并且不包含带有原型的标头时您所拥有的)被视为具有int
返回类型和未指定参数列表的函数。
编译器将执行默认提升(例如 float 到 double 等)并调用该函数。如果函数使用的参数数量与传递的数量不同,或者默认提升后的参数类型与函数的实现不兼容,则为未定义行为。
参见 ISO 9899:1999 (C99) §6.5.2.2,¶ 6:
如果表示被调用函数的表达式的类型不包含原型,则对每个参数执行整数提升,并将具有类型的参数float
提升为double
. 这些被称为默认参数提升. 如果参数的数量不等于参数的数量,则行为未定义。如果函数使用包含原型的类型定义,并且原型以省略号 (, ...) 结尾,或者提升后的参数类型与参数类型不兼容,则行为未定义。如果函数定义的类型不包含原型,并且提升后的参数类型与提升后的参数类型不兼容,则行为未定义,但以下情况除外:
- 一种提升类型是有符号整数类型,另一种提升类型是对应的无符号整数类型,并且值可以在两种类型中表示;
- 这两种类型都是指向字符类型或
void
.
在没有原型的情况下调用malloc()
,这可能会非常糟糕。 malloc()
接受一个size_t
参数并返回一个void *
指针。如果您的整数参数的默认提升结果产生一个大小与 不同的整数size_t
,您将有未定义的行为。如果int
大小不同void *
(例如,在 64 位系统上,int
通常是 32 位并且void *
将是 64 位),则返回的指针将被弄乱。