Страницы

Поиск по вопросам

воскресенье, 8 декабря 2019 г.

Как называется и работает такое динамическое выделение памяти?

#cpp


#include 

class T
{
    int x;
  public:
    T() { std::cout << "constr\n"; }
    ~T() { std::cout << "destr\n"; }
};

int main (void)
{
  char *buf = new char[sizeof(T)]; //13 line
  T *t = new(buf) T;

  t->~T();
}

Что это за выделение памяти такое new(buf)? То есть память выделяется в строчке 13,
а потом в строчке 14 не выделяется новая память под объект типа T, а берется уже выделенная
память из той, на которую указывает buf. То есть такой способ занимает меньше действий,
потому как можно раз выделить много памяти и потом использовать её с помощью new(buf)
при динамическом выделении объектов. Если это так, то указатель будет указывать на
следующий свободную ячейку памяти выделенного участка, когда будет к примеру ещё одно
выделение T *t2 = new(buf) T;, то есть buf указывает на участок памяти размером с размер
класса T и по этому перезапишет память, на которую указывает *t. И ещё не понятно как
это реализовано. Так как new - это оператор, то наверное есть его перегруженная версия,
которая принимает указатель на уже выделенную память и вторым параметром объект, который
нужно выделить в ней.
Вообщем это все догадки и возможно я кардинально не прав по этому поводу. Так что
лучше всего было бы, если бы вы написали как это называется, что бы можно было хоть
почитать где нибудь об этом способе или объяснили так, как вы считаете нужным.    


Ответы

Ответ 1



@mzarb, на самом деле никакой магии тут нет. Все довольно просто. Это Вы наделяете язык/компилятор какими-то особыми свойствами. Разберите пример Вашей (немного измененной) программы. avp@avp-xub11:~/hashcode$ cat mzarb.cpp #include #include class T { int x; public: T() { std::cout << "constr\n"; } ~T() { std::cout << "destr\n"; } void setX(int v) { x = v; } }; int main (void) { struct { char f1[2]; char f2[10]; } s; strcpy (s.f2,(char *)"1234"); std::cout << "f2 before: " << s.f2 << '\n'; T *t = new(s.f1) T; std::cout << "f2 after: " << s.f2 << '\n'; t->setX('z'); std::cout << "f2 again: " << s.f2 << '\n'; std::cout << "f2 offset: " << s.f2+2 << '\n'; t->~T(); } avp@avp-xub11:~/hashcode$ g++ mzarb.cpp avp@avp-xub11:~/hashcode$ ./a.out f2 before: 1234 constr f2 after: 1234 f2 again: f2 offset: 34 destr avp@avp-xub11:~/hashcode$ Видите, все предельно прозрачно. Никто ничего не проверяет. А рассуждения о надежности и безопасности это в реальности "развод лохов". Да, крестовый компилятор делает много проверок и для них язык заставляет Вас писать (и изучать) кучу лишнего.

Комментариев нет:

Отправить комментарий