Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> placement new, как удалять 
V
    Опции темы
d06osipov
Дата 21.12.2007, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 1.11.2006

Репутация: нет
Всего: нет



Я использую placement new, например так:
Код

char* ptr;
ptr=new char[sizeof(T)];
new(ptr) T;

Вопрос: как теперь вызвать delete, чтобы потом можно было снова по этому адресу объект создать?

И ещё. Верно ли, что placement new и delete гораздо более эффективны, чем обычные, потому что не надо искать свободное место в памяти?
PM MAIL   Вверх
Lazin
Дата 21.12.2007, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Код

ptr->~T();

Цитата(d06osipov @  21.12.2007,  11:20 Найти цитируемый пост)
И ещё. Верно ли, что placement new и delete гораздо более эффективны, чем обычные, потому что не надо искать свободное место в памяти? 

зависит от того где ты эту память собираешься брать))
PM MAIL Skype GTalk   Вверх
d06osipov
Дата 21.12.2007, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 1.11.2006

Репутация: нет
Всего: нет



1. А хорошо ли напрямую вызывать деструктор, нет ли более аккуратного способа?

Кроме того, помоему надо 
Код

reinterpret_cast<T*>(ptr)->~T();


2. Память я выделяю один раз обычным new. Правда ли, что потом placement new не делает ничего существенного, кроме вызова конструктора и инициализации локальных членов объекта (то есть время работы placement new несущественно больше времени работы конструктора и времени на инициализацию локальных членов).

Это сообщение отредактировал(а) d06osipov - 21.12.2007, 11:45
PM MAIL   Вверх
Lazin
Дата 21.12.2007, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Код

char* ptr;
ptr=new char[sizeof(T)];
T* pt = new(ptr) T;

pt->~T();

Цитата(d06osipov @  21.12.2007,  11:32 Найти цитируемый пост)
Правда ли, что потом placement new не делает ничего существенного, кроме вызова конструктора и инициализации локальных членов объекта

да правда, это бывает иногда необходимо, например для использования какого то блока памяти(выделенного заранее), или можно реализовать необычную стратегию управления памятью(хотя для этого обычно перегружают new delete)
PM MAIL Skype GTalk   Вверх
d06osipov
Дата 21.12.2007, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 1.11.2006

Репутация: нет
Всего: нет



Цитата(Lazin @ 21.12.2007,  12:23)
Код

pt->~T();


А такой вызов деструктора будет уничтожать локальные члены объекта *pt? Скажем, если pt->field объект некоторого класса, то вызов pt->~T() вызовет ли деструктор pt->field (как это происходит при обычном удалении)?
PM MAIL   Вверх
Alek86
Дата 21.12.2007, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



да, на то он и деструктор


--------------------
user posted image    user posted image
PM MAIL   Вверх
Daevaorn
Дата 21.12.2007, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



d06osipov, так лцучше не писать. зачем тебе морока с char?
Код

T* ptr;
ptr=operator new(sizeof(T));
new(ptr) T;
//...
ptr->~T();

PM MAIL WWW   Вверх
d06osipov
Дата 21.12.2007, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 1.11.2006

Репутация: нет
Всего: нет



Цитата(Daevaorn @ 21.12.2007,  14:49)
d06osipov, так лцучше не писать. зачем тебе морока с char?
Код

T* ptr;
ptr=operator new(sizeof(T));
new(ptr) T;
//...
ptr->~T();

Спасибо.

Но всё-таки, вызов деструктора, есть нечто большее, чем вызов обычной функции, так?
PM MAIL   Вверх
Lazin
Дата 21.12.2007, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(d06osipov @  21.12.2007,  15:59 Найти цитируемый пост)
Но всё-таки, вызов деструктора, есть нечто большее, чем вызов обычной функции, так? 

при вызове delete происходит неявный вызов деструктора, а код деструктора выполняет удаление всех членов класса, для них то-же вызывается деструктор, и тд. В случае размещающего оператора new вызывать delete не нужно, но удалять память выделенную под члены класса все равно придется, поэтому нужно его вызвать напрямую.
PM MAIL Skype GTalk   Вверх
d06osipov
Дата 21.12.2007, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 1.11.2006

Репутация: нет
Всего: нет



Цитата(Lazin @ 21.12.2007,  16:49)
при вызове delete происходит неявный вызов деструктора, а код деструктора выполняет удаление всех членов класса, для них то-же вызывается деструктор, и тд

Уверены, что именно код деструктора выполняет удаление всех членов, а не код delete?

Добавлено через 13 минут и 50 секунд
Всем спасибо, я убедился сам

Вот программа:
Код

#include <iostream>
using namespace std;

struct A
{ A()
  { cout<<"A construct"<<endl;
  }
 ~A()
  { cout<<"A destruct"<<endl;
  }
};

struct B
{ A a;
  
  B()
  { cout<<"B construct"<<endl;
  }
 ~B()
  { cout<<"B destruct"<<endl;
  }

};

int main()
{ B* b=reinterpret_cast<B*>(operator new(sizeof(B)));
  new(b) B;
  b->~B();
  operator delete((void*)b);
  return 0;
}


Вывод (g++) 
Код

A construct
B construct
B destruct
A destruct


Замечание. B*b=operator new(sizeof(B)); не работает, потому что operator new возвращает void*.

Я надеюсь, что это стандартный приём, и будет работать так на всех компиляторах.
PM MAIL   Вверх
onsql
Дата 21.12.2007, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 3.12.2007

Репутация: нет
Всего: 3



А как в эту теорию впишется результат работы такого кода?
Код

#include <iostream>
using namespace std;

struct A
{ A()
  { cout<<"A construct"<<endl;
  }
 ~A()
  { cout<<"A destruct"<<endl;
  }
};

struct B
{ A a;
  
  B()
  { cout<<"B construct"<<endl;
  }
 ~B()
  { cout<<"B destruct"<<endl;
  }

};

int main()
{
  void * mem = malloc(sizeof(B));
  B * bObj = new(mem) B();
  bObj->~B();
  free(mem);

  return 0;
}


Вывод на экран, аналогичен твоему примеру. 

PM MAIL   Вверх
d06osipov
Дата 24.12.2007, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 1.11.2006

Репутация: нет
Всего: нет



Хотя я не сторонник дедовских способов выделения памяти, в данном случае меня соверщенно не волнует этот процесс. placement new совершенно всё равно, каким именно образом выделена та память, куда будет размещён объект. 
PM MAIL   Вверх
Earnest
Дата 24.12.2007, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(onsql @  21.12.2007,  20:49 Найти цитируемый пост)
Вывод на экран, аналогичен твоему примеру. 

Прекрасно вписывается. А что смущает?



--------------------
...
PM   Вверх
onsql
Дата 24.12.2007, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 94
Регистрация: 3.12.2007

Репутация: нет
Всего: 3



Ну наверное я просто невнимательно прочитал.  Просто я так понял, что вот эта фраза
Цитата

Уверены, что именно код деструктора выполняет удаление всех членов, а не код delete?

относилось к тому, что в приведенному примере, именно благодаря вызову delete были вызваны деструкторы внутренних полей объекта b. На самом деле они были удалены в момент вызова  
Код

b->~B();

PM MAIL   Вверх
Earnest
Дата 24.12.2007, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Да, конечно. А деструктор был вызван благодаря delete  smile (но никто и не говорил, что это единственный способ его вызвать)


--------------------
...
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0577 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.