Вопрос

Простое тестовое приложение:

cout << new int[0] << endl;

результаты:

0x876c0b8

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

Это было полезно?

Решение

Из пункта 5.3.4/7

Когда значение выражения в direct-new-declarator равно нулю, вызывается функция выделения для выделения массива без элементов.

Из раздела 3.7.3.1/2

Эффект разыменования указателя, возвращаемого в качестве запроса на нулевой размер, не определен.

Также

Даже если размер пространства, запрошенного [с помощью new], равен нулю, запрос может завершиться ошибкой.

Это означает, что вы можете это сделать, но вы не можете юридически (четко определенным образом на всех платформах) разыменовывать полученную память - вы можете передать ее только в array delete - и вы должны удалить ее.

Вот интересное примечание (т. е. не являющееся нормативной частью стандарта, но включенное в пояснительных целях), приложенное к предложению из раздела 3.7.3.1 / 2

[32.Цель состоит в том, чтобы реализовать operator new() путем вызова malloc() или calloc(), поэтому правила по существу те же.C ++ отличается от C тем, что требует, чтобы нулевой запрос возвращал ненулевой указатель.]

Другие советы

Да, это законно - выделять массив нулевого размера подобным образом.Но вы также должны удалить его.

Что говорит об этом стандарт?Всегда ли законно "выделять" пустой блок памяти?

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

Если бы вы выделили более одного из этих объектов, то обнаружили бы, что у них разные адреса.

Да, совершенно законно выделять 0 размер блока с new.Вы просто не можете сделать с ним ничего полезного, поскольку у вас нет действительных данных для доступа. int[0] = 5; это незаконно.

Тем не менее, я считаю, что стандарт допускает такие вещи, как malloc(0) чтобы вернуться NULL.

Вам все равно нужно будет delete [] любой указатель, который вы также получите обратно из распределения.

Любопытно, что C ++ требует, чтобы operator new возвращал законный указатель даже когда запрашиваются нулевые байты.(Требование этого странно звучащего поведение упрощает вещи в других частях языка.)

Я нашел Действующее Третье издание C ++ сказано примерно так в "Пункте 51:Придерживайтесь правил при написании нового и удалении".

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top