В ситуации, когда я хочу избежать динамического выделения памяти, я заменяю новый оператор процессом, который по существу использует память некоторого статически выделенного объекта (класс 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 в комментариях выше), но результат, который я получаю:
Создание нового объекта
Создание нового объекта
Создание нового объекта
Почему конструктор вызывается трижды? Я бы ожидал только вызовов конструктора статическим объектом и вызовом нового размещения. Я пробовал отслеживать код с помощью gdb, но для меня это не имеет смысла, поскольку позиция //3
равна where
, инициируется третий вызов конструктора.
Причина, по которой я хочу знать, заключается в том, что возник случай, когда этот дополнительный вызов конструктора вызывает нежелательные побочные эффекты; до сих пор этот дополнительный вызов оставался незамеченным.
#0 Object::Object (this=0x555555756160 <Storage>) at placement.cpp:7 #1 0x0000555555554a4f in main () at placement.cpp:31
(строка 7 — этоcout
, а строка 31 — единственная строка вmain
) - person Lorah Attkins   schedule 21.01.2020Storage::where
, вторая — вoperator new
, а третья — вmain
-функции. - person Simon Kraemer   schedule 21.01.2020operator new
: она должна только выделять память, а не создавать объекты. Поэтому он не должен делать размещение-новым. - person Some programmer dude   schedule 21.01.2020