Подтвердить что ты не робот

Разница между <stdlib.h> и <malloc.h>

Когда я использую malloc в программе на C, я получаю предупреждение:

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)

4b9b3361

Ответ 1

Заголовок <malloc.h> устарел (и довольно специфичен для Linux, на котором он определяет нестандартные функции, такие как mallinfo (3)). Используйте <stdlib.h> вместо этого, если вам просто нужно malloc (3) и соответствующие стандартные функции (например, free, calloc, realloc....). Обратите внимание, что <stdlib.h> определяется C89 (и позже) стандартами, но не <malloc.h>

Посмотрите /usr/include/malloc.h, вы найдете там некоторые нестандартные функции (например, malloc_stats (3) и т.д.) - кроме malloc....

И gcc не связывать файлы заголовков, а библиотеки. Прочтите книгу Левина о линкерах и загрузчиках для более подробной информации.

Если вы не включаете заголовки (и прямо не объявляете malloc самостоятельно, что было бы плохой идеей), malloc неявно объявляется как возвращающее значение int (что неверно). Я предлагаю вам передать по крайней мере флаг -Wall на gcc при его использовании.

Вы также можете передать -v в gcc, чтобы понять актуальные программы: cc1 - это собственно компилятор (код сборки), as ассемблер, ld компоновщик и collect2 внутренняя утилита, которая вызывает компоновщик.

Ответ 2

stdlib.h является стандартным заголовком C, который объявляет, среди прочего, функции malloc(), calloc(), free(). Это заголовок, который вы должны включить.

malloc.h - это нестандартный заголовок, который можно найти во многих системах, где он часто определяет дополнительные функции, специфичные для реализации malloc, используемые этой платформой.

Если вы не включили ни одно из них, нет значения по умолчанию, однако, если вы вызываете malloc() без предварительного объявления функции malloc, C будет считать, что прототип функции int malloc();, что часто бывает неправильным. В дополнение к заголовкам компиляторы C обычно ссылаются на стандартную библиотеку, например. glibc на Linux, где выполняется реализация malloc.

Обратите внимание, что существует разница между файлами заголовков и библиотеками. Заголовочные файлы объявляют вещи, например, структуры и прототипы функций. Библиотеки содержат реализацию, скомпилированный код. Вы ссылаетесь на библиотеку, и вы # включаете файлы заголовков.

Ответ 3

Заголовки объявляют разные наборы функций, но как forward-declare malloc.

Если вы не включили ни один из них, у вас нет прототипа для malloc, следовательно, это предупреждение. Но вы ссылаетесь на ту же функцию независимо, потому что есть только одна функция malloc. Он просто провозглашен в двух местах. Форвардные объявления не существуют для ссылки на функцию malloc, они там, поэтому компилятор может исправить правильный код вокруг вызова, указать аргументы и прочитать возвращаемое значение.

Обратите внимание, что <malloc.h> не является стандартным. Я не думаю, что stdlib.h когда-либо включал malloc.h в GCC, но вы можете себе представить, что с этого момента можно было бы предоставить необходимое объявление.

Ответ 4

Чтобы узнать разницу, вы должны прочитать их содержимое для себя.

По умолчанию gcc не читает.

Когда вы их прочтете, вы увидите, что они объявляют malloc по-другому.

Ответ 5

<malloc.h> не является стандартным заголовком и, следовательно, не переносится. Стандарт ставит malloc() et al. в <stdlib.h>.

Ответ 6

Другие уже обсудили различия между < malloc.h > и < stdlib.h >

Что касается предупреждения, когда ни один из них не включен, это определение того, как работают C-функции. Функция без прототипа (это то, что у вас есть, когда вы не объявляете свой собственный и не включаете заголовок с одним) рассматривается как функция с типом возврата int и неопределенным списком аргументов.

Компилятор будет выполнять промо-акции по умолчанию (например, float to double и другие) и вызывается функция. Если количество аргументов, используемых функцией, отличается от числа, прошедшего, или если типы аргументов после промоакций по умолчанию несовместимы с реализацией функции, это поведение undefined.

См. ISO 9899: 1999 (C99) и раздел 6.5.2.2, & para; 6:

Если выражение, обозначающее вызываемую функцию, имеет тип, который не содержит прототип, то для каждого аргумента выполняются целые рекламные акции, а аргументы с типом float продвигаются до double. Они называются рекламными акциями по умолчанию. Если количество аргументов не равно числу параметров, поведение undefined. Если функция определена с типом, который включает прототип, и либо прототип заканчивается на эллипсис (,...), либо типы аргументов после продвижения по службе не совместимы с типами параметров, поведение undefined. Если функция определена с типом, который не включает прототип, а типы аргументов после продвижения по службе не совместимы с типами параметров после продвижения по службе, поведение undefined, за исключением следующих случаев:

  • один продвинутый тип - это целочисленный тип со знаком, другой продвинутый тип - это соответствующий целочисленный тип без знака, и значение представляется в обоих типах;
  • Оба типа являются указателями на квалифицированные или неквалифицированные версии типа символа или void.

В случае вызова malloc() без прототипа это может быть очень плохо. malloc() принимает аргумент size_t и возвращает указатель void *. Если результат по умолчанию вашего целочисленного аргумента дает целое число, отличающееся по размеру от size_t, у вас будет поведение undefined. И если int отличается от void * (например, в 64-битных системах, где int часто 32 бит, а void * будет 64-битным), возвращаемый указатель будет испорчен.