Почему malloc (0) возвращает ненулевой адрес в Windows? - PullRequest
11 голосов
/ 15 марта 2012

Приведенный ниже код возвращает адрес при выполнении в Windows, хотя я ожидал, что он вернет NULL.

int main()
{
   char *ptr = NULL;
   ptr = malloc(0);
   printf("malloc returned = %u\n", ptr);

}

Что могло быть причиной такой реализации malloc? Есть ли причина этого?

Поскольку это 0-байтовая память, я не экспериментировал с записью каких-либо данных. Но можно ли вообще использовать эту память для чего-либо?

Ответы [ 5 ]

9 голосов
/ 15 марта 2012

Это просто минимальный размер, который вы запрашиваете.А поскольку в куче Win32 нет блоков нулевой длины, вы можете:

void *p = malloc(0);
// ... do some stuff in between...
realloc(p, n);

, что в основном должно привести к повторному использованию блока кучи (если вам повезет и новый размер мал),Незначительная оппортунистическая оптимизация (или замедление, в зависимости от контекста и уровня кофе в крови).

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

8 голосов
/ 15 марта 2012

Чтобы ответить на вторую часть вашего вопроса «нет», память не может быть использована ни для чего, поскольку «доступная ее часть» составляет 0 байт, начиная с возвращенного адреса.

IIRC гарантировано, однако, что если реализация вернет ненулевое значение, то это будет отличный адрес от любого другого выделенного в настоящее время блока памяти. Таким образом, теоретически вы можете использовать адрес в качестве временного уникального идентификатора (типа указателя), хотя очевидно, что существует множество других способов получения уникального идентификатора. И даже если вы собираетесь использовать его для этого, malloc(1) будет работать так же хорошо, как и malloc(0) и будет более переносимым.

7 голосов
/ 15 марта 2012

Ответы на вопросы в comp.lang.c FAQ: http://c -faq.com / ansi / malloc0.html

Стандарт ANSI / ISO гласит, что онможет сделать либо;поведение определяется реализацией (см. вопрос 11.33).Переносимый код должен либо заботиться о том, чтобы не вызывать malloc (0), либо быть готовым к возможности нулевого возврата.

3 голосов
/ 15 марта 2012

стандарт говорит, что может сделать либо

http://pubs.opengroup.org/onlinepubs/009695399/functions/malloc.html

0 голосов
/ 18 августа 2017

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

Однако, как уже упоминалось, это отличный способ написания непереносимого кода.Однако это НЕ то же самое, что нелегальный код, и вполне допустимо для реализации, поддерживающей его (как, видимо, делает Windows).

...