Ответ 1
Да, вы можете. Я считаю, что это гарантировано несколькими положениями.
-
[expr.new]/10 - Акцент на мой
Новое выражение передает объем пространства, запрошенный для функция распределения как первый аргумент типа std:: size_t. Это аргумент должен быть не меньше размера создаваемого объекта; он может быть больше размера создаваемого объекта, только если объект представляет собой массив. Для массивов char и unsigned char, разница между результатом нового выражения и адресом возвращаемый функцией распределения, должен быть целым кратным строжайшее требование основного выравнивания ([basic.align]) любого тип объекта, размер которого не превышает размер массива, создано. [Примечание: поскольку предполагается, что функции распределения возвращаются указатели на хранилище, которые соответствующим образом выровнены для объектов любого тип с фундаментальным выравниванием, это ограничение на распределение массива служебные данные позволяют распространять идиому выделения массивов символов в какие объекты других типов будут позже размещены. - конечная нота]
Что мне читает, как новое выражение должно создать объект (предполагая его не типа массива) по точному адресу, возвращаемому функцией распределения. Поскольку вы используете встроенное размещение new, это приведет нас к следующему
-
Эти функции зарезервированы, программа на С++ может не определять функции которые заменяют версии в стандартной библиотеке С++ ([ограничения]). Положения ([basic.stc.dynamic]) не применяются к этим зарезервированным формам размещения оператора new и оператора delete.
void* operator new(std::size_t size, void* ptr) noexcept;
Возвращает: ptr.
Примечания: Преднамеренно не выполняет никаких других действий.
Что гарантирует адрес, который вы передаете в выражение, является точным адресом выделенного вами массива символов. Это потому, что преобразования в
void*
не меняют адрес источника.
Я думаю, это достаточно, чтобы обещать, что адреса одинаковы, даже если указатели не являются взаимозаменяемыми в целом. Итак, согласно [expr.eq]/1 (спасибо @T.C.):
Два указателя одного типа сравнивают одинаковые, если и только если они оба нулевые, оба указывают на одну и ту же функцию, или оба представляют одинаковые адрес ([basic.compound]).
Сравнение должно иметь значение true, опять же, потому что адреса одинаковы.