Я прошу прощения, если я пропустил важный момент, который каким-то образом скрыт в вопросе, и я не вижу его.Но относительно этой центральной строки:
std::auto_ptr<Base> p(new((void*)(new char[size])) Packet());
Вот что я могу сказать об этом:
В конце вызов конструктора должен быть Packet
, а не Packet()
, хотя на практике компилятор может принять его как есть, и это может не иметь никакого значения
Внутреннее распределение new char[size]
использует распределитель массива new []
.Ссылка CPP указывает на выражение new [array_n]
:
Обратите внимание, что может быть выделено больше, чем size_of (тип) * array_n из-за закодированной дополнительной информациикомпилятором (таким как размер массива, так как эта информация необходима для правильной деструкции объектов в массиве).
Теперь внешний вызов распределителя new ((void*)(...))
экземпляр размещения нового , который описан здесь следующим образом:
void* operator new ( std::size_t, void* ptr );
ничего не делает, возвращает ptr.
Другими словами, может произойти , когда вызов new []
заставляет компилятор выделить больше памяти, чем строго требуется массивом и кодировать информацию, связанную с размером в дополнительном пространстве.Однако, поскольку размещение new ничего не делает, оно не обрабатывает и не удаляет дополнительную информацию.
Но, поскольку использование std::auto_ptr
подразумевает, что это освобождение будетПри использовании delete
(и , а не delete []
) дополнительная информация не будет должным образом освобождена, следовательно, может произойти утечка памяти или еще хуже.
Редактировать: Чтобы не полагаться только на ссылку CPP, соответствующие части C ++ стандарта N3337 следующие:
- § 18.6.1.2 гласит, что только
delete
должно бытьиспользуется для освобождения пространства, выделенного на new
, и соответственно delete []
для пространства, выделенного на new []
- § 18.6.1.3 прямо заявляет, что формы размещения
new
и new []
не выполняют никакихдействие.Это подразумевает, что ни один из них не может быть использован для «преобразования» пространства одного объекта в пространство массива.
Теперь, возможно, реальный вопрос заключается в том, является ли применение размещения новым предложенным в вопросебудет действительным, если только delete []
был использован для освобождения места позже.Возможно, ответ не определен (что следует интерпретировать как эквивалент «Нет»).