Выделение памяти и размер 0: могу ли я получить утечки памяти? - программирование
Подтвердить что ты не робот

Выделение памяти и размер 0: могу ли я получить утечки памяти?

Мой вопрос находится в моем комментарии к коду:

int* a = new int[0];// I've expected the nullptr according to my logic...
bool is_nullptr = !a; // I got 'false'
delete[] a; // Will I get the memory leaks, if I comment this row?

Спасибо.

4b9b3361

Ответ 1

Для С++ 11 и с учетом вашего кода:

int* a = new int[0];

Zero - это юридический размер, согласно 5.3.4/7:

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

Вызывается оператор в соответствии с 18.6.1.2 (выделение мое):

void * operator new [] (std:: size_t size);

...

3 Требуемое поведение: Тот же , что и для оператора new (std:: size_t). Это требование является обязательным для замены версии этой функции.

4 Поведение по умолчанию: возвращает оператор new (размер).

... ссылка 18.6.1.1...

void* operator new(std::size_t size);

3 Требуемое поведение: Верните указатель не нуль в подходящую выровненную память (3.7.4) или вызовите bad_- исключить исключение. Это требование является обязательным для замены версии этой функции.

Итак, возвращаемый указатель должен быть не нулевым.

Вам понадобится delete[] после этого.

Ответ 2

В С++ 03 new int[0] возникает поведение undefined, потому что значение между [] должно быть строго положительным значением - ноль не является хорошим (5.3.4/6 "Новое" ). Поэтому, спрашивая, есть ли утечка памяти после этого, в каком-то смысле бессмысленно.

В С++ 11 new int[0] приводит к вызову распределителю для распределения массива нулевой длины (5.3.4/7 "Новый" ). Если запрос распределения успешно завершен, возвращается указатель - в стандарте нет ничего, что говорит о том, сколько памяти содержит указатель, на который указывает этот указатель, кроме того, что он должен быть как минимум запрошенным размером. Однако он имеет по крайней мере эффект выделения хотя бы одного символа, потому что этот адрес не может быть возвращен распределителем снова, пока он не будет освобожден. На практике накладные расходы на бухгалтерию будут более одного символа.

Ответ 3

Да, есть утечка, и она не зависит от реализации.

Это новое выражение не может дать нулевой указатель. Он выделяет память, вызывая operator new[], который требуется для "возврата ненулевого указателя на подходящую выровненную память, или же выкинуть исключение bad_alloc" (см. С++ 11 §18.6.1.1/3 и §18.6. 1.2/3).

Кроме того, требования функции распределения (§3.7.4.1) требуют, чтобы каждый вызов функции распределения возвращал указатель, отличный от всех других указателей, которые были выделены, но еще не освобождены. Таким образом, реализация не может просто иметь один указатель "пустое размещение", который он всегда возвращает.

Это, каждое новое выражение в форме массива выделяет что-то, даже если степень равна нулю. Если вы не освободите этот объект через delete[], вы его просочились.

Ответ 4

Да, без delete произойдет утечка памяти.

Каждый new должен быть сопряжен с delete. Даже если размер выделенного программиста равен 0. Allocator может выделять больше памяти, чем запрошено, из-за требований к выравниванию, издержек управления или чего-либо еще.

Ответ 5

В этом случае реализована реализация, будет ли вы возвращен nullptr или нет, но, вы должны быть осторожны, чтобы вы не разыменовали этот указатель и не вызывали delete приведет к утечке памяти.

W.r.t для вызова delete правило прост:
"Если вы вызываете new, вы должны позвонить delete."

Исправление:
Как ясно из цитат из других ответов, он не может вернуть вам nullptr.