Почему среда выполнения не может решить применить delete или delete [] вместо программатора? - PullRequest
18 голосов
/ 06 декабря 2011

Я прочитал, что оператор delete[] необходим, потому что среда выполнения не хранит информацию о том, является ли выделенный блок массивом объектов, для которых требуются вызовы деструктора, или нет, но фактически хранит информацию о том, где находится памятьхранится ли выделенный блок, а также, конечно же, размер блока.
Потребовалось бы еще один бит метаданных, чтобы запомнить, нужно ли вызывать деструкторы при удалении или нет, так почему бы просто не сделать это?

Я почти уверен, что есть хорошее объяснение, я не подвергаю сомнению это, я просто хочу знать это.

Ответы [ 4 ]

10 голосов
/ 06 декабря 2011

Я думаю, причина в том, что C ++ не заставляет вас делать то, что вам не нужно. Это добавит дополнительные метаданные, и если кто-то их не использует, то на них будут наложены дополнительные издержки, в отличие от целей разработки языка C ++.

Если вам нужна описанная вами возможность, C ++ предоставляет способ. Он называется std::vector, и вы почти всегда должны предпочитать его, контейнер другого типа или умный указатель на raw new и delete.

.
4 голосов
/ 06 декабря 2011

Это в основном сводится к языковому дизайну, который не хочет накладывать слишком много ограничений на разработчиков.Многие среды выполнения C ++ используют malloc() для ::operator new () и free() (более или менее) для ::operator delete ().Стандарт malloc / free не обеспечивает бухгалтерию, необходимую для записи ряда элементов, и не дает возможности определить размер malloc во время free.Добавление еще одного уровня манипулирования памятью между new Foo и malloc для каждого отдельного объекта - это, с точки зрения C / C ++, довольно большой скачок в сложности / абстракции.Помимо прочего, добавление этих накладных расходов к каждому объекту может испортить некоторые подходы к управлению памятью, которые разработаны с учетом размера объектов.

4 голосов
/ 06 декабря 2011

C ++ позволяет вам работать максимально эффективно, поэтому, если бы им пришлось отслеживать количество элементов в блоке, которое было бы просто дополнительными 4 байтами, используемыми на блок.

Это может быть полезно для многихлюди, но это также мешает полной эффективности для людей, которые не против поставить [].

Это похоже на разницу между c ++ и Java.Java может быть намного быстрее в программировании, потому что вам никогда не придется беспокоиться о сборке мусора, но C ++, если он запрограммирован правильно, может быть более эффективным и использовать меньше памяти, потому что ему не нужно хранить какие-либо из этих переменных, и вы можете решить, когдаудалить блоки памяти.

3 голосов
/ 06 декабря 2011

Здесь необходимо прояснить две вещи.

Первое: предположение, что malloc сохраняет размер, который вы просили.

Не совсем.malloc заботится только о предоставлении достаточно большого блока.Хотя по соображениям эффективности он, вероятно, не будет перераспределять много, он все равно, вероятно, даст вам блок «стандартного» размера, например, блок 2^n байтов.Поэтому реальный размер (например, количество фактически выделенных объектов) фактически неизвестен.

Второе: требуется дополнительный бит

Действительно, необходимая информациячтобы данный объект знал, является ли он частью массива или нет, это просто лишний бит.Логически.

Что касается реализации, хотя: куда бы вы на самом деле поместили этот бит?

Память, выделенная для самого объекта, вероятно, не должна быть затронута, объект использует ее в конце концов,Итак?

  • на некоторой платформе, это может быть сохранено в самом указателе (некоторые платформы игнорируют часть битов), но это не переносимо
  • , так что это потребует дополнительныххранилище, по крайней мере, один байт, за исключением того, что при проблемах выравнивания он может составлять 8 байтов.

Демонстрация: (не убедительно, как указано в sth, см. ниже)

// A plain array of doubles:
+-------+-------+-------
|   0   |   1   |   2   
+-------+-------+-------

// A tentative to stash our extra bit
+-------++-------++-------++
|   0   ||   1   ||   2   ||
+-------++-------++-------++

// A correction since we introduced alignment issues
// Note: double's aligment is most probably its own size
+-------+-------+-------+-------+-------+-------
|   0   |  bit  |   1   |  bit  |   2   |  bit
+-------+-------+-------+-------+-------+-------

Humpf!

РЕДАКТИРОВАТЬ

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

Допустимо ли, чтобы все указатели были в два раза больше только для того, чтобы вы могли хранить этот дополнительный бит?Я думаю, что для большинства людей это будет.Но C ++ не предназначен для большинства людей, он в первую очередь предназначен для людей, которые заботятся о производительности, будь то скорость или память, и поэтому это недопустимо.

КОНЕЦ РЕДАКТИРОВАНИЯ

Так, каков правильный ответ?Правильный ответ заключается в том, что восстановление информации, потерянной системой типов, является дорогостоящим.К сожалению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...