<stdlib.h>和<malloc.h> </malloc.h> </stdlib.h>之间的区别

时间:2012-10-19 11:29:18

标签: c gcc malloc

当我在C程序中使用malloc时,我收到警告:

warning: incompatible implicit declaration of built-in function 'malloc' [enabled by default]

然后,我可以包含<malloc.h><stdlib.h>以摆脱warning,虽然它也可以在没有它的情况下运行。

所以我想知道,当我不包含任何内容时,这些标题与gcc链接之间有什么区别?

(我正在ubuntu 12.04 64-bit使用gcc 4.6.3

6 个答案:

答案 0 :(得分:48)

不推荐<malloc.h>标头(非常特定于Linux,它定义了非标准函数,如mallinfo(3))。如果您只需要malloc(3)和相关的标准功能(例如<stdlib.h>freecalloc ....),请使用realloc。请注意,<stdlib.h>C89(及更高版本)标准定义,但不是<malloc.h>

调查/usr/include/malloc.h你会发现一些非标准功能(例如malloc_stats(3)等...) - 除了malloc ....

并且gcc不会链接头文件,而是库。阅读Levine关于linkers & loaders的书,了解更多信息。

如果你没有包含任何标题(并且不自己明确声明malloc,这可能是一个坏主意),malloc被隐式声明为返回一些int值(是错的)。我邀请您在使用时至少将-Wall标记传递给gcc

您也可以将-v传递给gcc以了解所涉及的实际程序:cc1是正确的编译器(生成汇编代码),as汇编程序,{{ 1}}链接器,collect2是调用链接器的内部实用程序。

答案 1 :(得分:9)

stdlib.h 是一个标准的C头,它声明了malloc(),calloc(),free()函数。这是您应该包含的标题。

malloc.h 是一个非标准的标头,可在许多系统中找到,它通常定义特定于该平台使用的malloc实现的附加功能。

如果你不包含任何这些,那么没有默认值,但是如果你在没有事先声明malloc函数的情况下调用malloc(),C将假设函数原型是int malloc();,这通常是错误的。除了标题之外,C编译器通常链接到标准库,例如标准库。 Linux上的glibc,malloc的实现所在。

请注意,头文件和库之间存在差异。头文件声明了一些东西,比如结构和函数原型。库包含实现,编译代码。您链接到库,并#include头文件。

答案 2 :(得分:6)

标题声明了不同的函数集,但都是forward-declare malloc

如果您不包含其中任何一个,那么您没有malloc的原型,因此警告。但无论如何都要链接相同的函数,因为只有一个malloc函数。它只是在两个地方向前宣布。前向声明不是为了帮助链接malloc函数,它们就在那里,以便编译器可以在调用周围发出正确的代码,指定参数并读取返回值。

请注意<malloc.h>不是标准的包含。我不认为stdlib.h曾在GCC中包含malloc.h,但您可以想象,因为这是提供必要声明的一种方式。

答案 3 :(得分:3)

<malloc.h>不是标准标头,因此不可移植。该标准提出malloc()等。在<stdlib.h>

答案 4 :(得分:2)

其他人已经讨论过&lt; malloc.h&gt;之间的区别和&lt; stdlib.h&gt;

至于包含两者的警告,那就是C函数如何工作的定义。没有原型的函数(当你没有声明自己的函数并且不包含带有标题的函数时,你拥有的函数)被视为具有int返回类型和未指定<的函数。 / em>参数列表。

编译器将执行默认促销(例如float to double和其他)并调用该函数。如果函数使用的参数数量与传递的数量不同,或者默认促销后的参数类型与函数的实现不兼容,则它是未定义的行为。

见ISO 9899:1999(C99)§6.5.2.2,¶6:

  

如果表示被调用函数的表达式具有不包含原型的类型,则对每个参数执行整数提升,并将类型为float的参数提升为double。这些被称为默认参数促销。如果参数数量不等于参数数量,则行为未定义。如果函数是使用包含原型的类型定义的,并且原型以省略号(,...)结尾,或者促销后的参数类型与参数类型不兼容,则行为未定义。如果使用不包含原型的类型定义函数,并且促销后的参数类型与促销后的参数类型不兼容,则行为未定义,但以下情况除外:

     
      
  • 一个提升类型是有符号整数类型,另一个提升类型是相应的无符号整数类型,并且该值可在两种类型中表示;
  •   
  • 这两种类型都是指向字符类型的合格或非限定版本或void的指针。
  •   

如果在没有原型的情况下调用malloc(),则可能非常糟糕。 malloc()接受size_t参数并返回void *指针。如果整数参数的默认提升结果产生的大小与size_t大小不同,则您将具有未定义的行为。如果intvoid *的大小不同(例如,在64位系统上,int通常为32位,void *将为64位,则返回的指针将被弄乱。

答案 5 :(得分:1)

要了解其中的差异,您应该自己阅读其内容。

默认情况下,gcc不读取任何内容。

当您阅读它们时,您会看到它们以不同方式声明malloc