Обновление: После некоторого обсуждения я понимаю, что мой ответ больше не относится к вопросу. Я оставлю это здесь, но реальный ответ определенно все еще необходим.
Я буду рад поддержать этот вопрос некоторым вознаграждением, если хороший ответ не будет найден в ближайшее время.
Я повторю этот вопрос здесь, насколько я понимаю, в надежде, что более короткая версия может помочь другим понять, о чем спрашивают. Вопрос:
Всегда ли правильна следующая конструкция? arr == addr
в конце?
void * addr = std::malloc(N * sizeof(T));
T * arr = ::new (addr) T[N]; // #1
Мы знаем из стандарта, что # 1 вызывает вызов ::operator new[](???, addr)
, где ???
- неопределенное число, не меньшее N * sizeof(T)
, и мы также знаем, что этот вызов возвращает только addr
и не имеет других эффектов , Мы также знаем, что arr
смещено от addr
соответственно. не знает, что мы знаем, является ли память, на которую указывает addr
, достаточно большой или как мы узнали бы, сколько памяти выделить.
Вы, кажется, путаете несколько вещей:
Ваш пример звонит operator new[]()
, а не operator new()
.
Функции распределения ничего не создают . Они выделяют .
В результате выражение T * p = new T[10];
вызывает:
вызов operator new[]()
с аргументом размера 10 * sizeof(T) + x
,
десять вызовов к конструктору по умолчанию T
, фактически ::new (p + i) T()
.
Единственная особенность в том, что выражение для нового массива запрашивает больше памяти, чем то, что используется данными самого массива. Вы не видите ничего из этого и не можете использовать эту информацию иначе, как при молчаливом согласии.
Если вам интересно, сколько памяти фактически было выделено, вы можете просто заменить функции выделения массивов operator new[]
и operator delete[]
и заставить их распечатать фактический размер.
Обновление: Как случайная часть информации, вы должны заметить, что новые глобальные функции размещения должны быть неактивными. То есть, когда вы создаете объект или массив на месте следующим образом:
T * p = ::new (buf1) T;
T * arr = ::new (buf10) T[10];
Тогда соответствующие вызовы ::operator new(std::size_t, void*)
и ::operator new[](std::size_t, void*)
ничего не делают, но возвращают свой второй аргумент. Однако вы не знаете, на что buf10
должен указывать: он должен указывать на 10 * sizeof(T) + y
байт памяти, но вы не можете знать y
.