В ситуации, когда я хочу избежать динамического выделения памяти c, я заменяю новый оператор процессом, который по существу использует память некоторого статически распределенного объекта (класс Storage
ниже). Ниже приведен минимальный рабочий пример:
#include <cassert>
#include <iostream>
struct Object {
Object() { std::cout << "Creating a new object\n"; }
static void *operator new(size_t);
static void operator delete(void *p);
};
static struct {
Object where;
bool allocated = false;
} Storage; // 1
void *Object::operator new(size_t) {
assert(!Storage.allocated);
auto p = ::new (&Storage.where) Object; // 2
Storage.allocated = true;
return p;
}
void Object::operator delete(void *p) {
assert(Storage.allocated);
static_cast<Object *>(p)->~Object();
Storage.allocated = false;
}
int main() { Object *obj = new Object; } // 3
Мой вопрос касается количества обращений к конструктору . Когда я запускаю вышеуказанную программу, я ожидаю дважды вызвать конструктор (помеченный как 1 и 2 в комментариях выше), но получаю вывод:
Создание новой объект
Создание нового объекта
Создание нового объекта
Почему конструктор называется трижды? Я ожидал бы только вызовов конструктора от объекта stati c и вызова для размещения new. Я попытался отследить код с помощью gdb, но для меня это не имеет смысла, так как позиция //3
равна where
, когда происходит третий вызов конструктора.
Причина, которую я хочу знать, заключается в том, что возник случай, когда этот дополнительный вызов конструктора вызывает нежелательные побочные эффекты; до сих пор этот дополнительный звонок был незамеченным.