Почему malloc (0) возвращает ненулевой адрес в Windows?

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

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

}

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

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

Ответ 1

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

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

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

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

Ответ 2

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

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

Ответ 3

Это ответило на часто задаваемые вопросы по comp.lang.c: http://c-faq.com/ansi/malloc0.html

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

Ответ 5

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

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