Нулевой размер malloc

Очень простой вопрос, я сделал следующую программу:

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

И это не означает, что моя машина. Это переносимое поведение stdlib malloc и бесплатно, или я ищу проблемы?

Изменить: то, что кажется не переносным, - это значение, возвращаемое malloc. Речь идет о malloc (0) + свободной комбинации, а не о значении ptr.

Ответ 1

Поведение определяется реализацией, вы получите либо указатель NULL, либо адрес. Однако вызов бесплатного для полученного указателя не должен вызывать проблемы, поскольку:

  • free (NULL) в порядке, операция не выполняется
  • free (address) в порядке, если адрес был получен от malloc (или других, таких как calloc и т.д.).

Ответ 2

Разрешено возвращать NULL, и ему разрешено возвращать указатель не-NULL вы не можете разыгрывать. Оба способа санкционированы стандартом (7.20.3):

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

Ответ 3

Извините за беспокойство, я должен был прочитать страницы руководства:

malloc() выделяет байты размера и возвращает указатель на выделенную память. Память не очищается. Если размер равен 0, malloc() возвращает либо NULL, либо  уникальное значение указателя, которое впоследствии может быть успешно передано в free().

free() освобождает пространство памяти, на которое указывает ptr, который должен был быть возвращен предыдущим вызовом malloc(), calloc() или realloc(). В противном случае, или если  free (ptr) уже вызывается раньше, происходит поведение undefined. Если ptr равно NULL, операция не выполняется.

Кажется, это правда, по крайней мере, для gnu libc

Ответ 4

Обновлено с учетом комментариев libt и Pax:

Поведение вызова malloc (0) зависит от реализации или, другими словами, не переносимого и undefined.

Ссылка на CFaq вопрос для более подробной информации.

Ответ 5

Согласно стандарту c

7.20.3 Если размер запрашиваемого пространства равен нулю, поведение определяется реализацией: возвращается нулевой указатель или поведение такое, как если бы размер был некотором ненулевым значением, за исключением того, что возвращаемый указатель не должен использоваться для доступа к объекту.

Ответ 7

По моему опыту, я видел, что malloc (0) возвращает указатель, который можно освободить. Но это вызывает SIGSEGV в более поздних операциях malloc(). И это было очень случайным.

Когда я добавил чек, чтобы не вызывать malloc, если размер, который нужно выделить, равен нулю, я избавился от этого.

Итак, я бы предложил не выделять память для размера 0.

-Ashutosh