C++Builder
  Начало   Форум   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: new->auto_ptr  (Прочитано 2136 раз)
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 784


new->auto_ptr
« : 04 Декабрь 2014, 12:11:10 »

В коде, представленном на рисунке, память выделяется оператором new. Затем идет присвоение конструкции auto_ptr в другом блоке кода. При завершении блока, auto_ptr корректно удалить блок выделенный переменной _return?
Спасибо.
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


Re: new->auto_ptr
« Ответ #1 : 04 Декабрь 2014, 13:31:12 »

Привет. Не понял вопроса. Эти два блока (функции) - насколько можно судить - совершенно не связаны между собой. В первом память выделяется и освобождается вручную, а во втором - автоматически. Переменная _return относится только к 1-му блоку... Пример оформления первого блока в 2 вариантах (ручное и автоматическое управление памятью):
Код
// ВАРИАНТ 1 (РУЧНОЕ УПРАВЛЕНИЕ ПАМЯТЬЮ)
TMemoryStream* _return = new TMemoryStream();
try {
 Image1->Bitmap->SaveToStream(_return);
}
__finally {
 delete _return;
}
 
// ВАРИАНТ 2 (АВТОМАТИЧЕСКОЕ УПРАВЛЕНИЕ ПАМЯТЬЮ) - ПРЕДПОЧТИТЕЛЬНЫЙ ВАРИАНТ
std::auto_ptrTMemoryStream> _return1 (new TMemoryStream());
Image1->Bitmap->SaveToStream(_return1.get());
 
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 784


Re: new->auto_ptr
« Ответ #2 : 04 Декабрь 2014, 16:03:23 »

Как не связаны? При нажатии на кнопку вызывается функция через this и результат выполнения возвращается и учавствует в инициализации lStrem.
Поэтому возник вопрос ведь оператор new выделил память в одном блоке кода, а затем используется в другом блоке кода.
« Последнее редактирование: 04 Декабрь 2014, 16:15:09 от SilverFish » Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


Re: new->auto_ptr
« Ответ #3 : 04 Декабрь 2014, 20:24:31 »

Да, сразу не увидел 
Нет, здесь ничего страшного - SaveImage возвращает либо указатель на созданный объект, либо в случае ошибки - нуль. auto_ptr в своем конструкторе забирает владение этим объектом и при выходе за область видимости (в своем деструкторе) освобождает память, так что с этой стороны все ок. Только функцию сохранения надо немного изменить - после создания auto_ptr необходимо дополнительно проверить на нулевой указатель:
Код
if (!lStream.get()) return;
 
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 784


Re: new->auto_ptr
« Ответ #4 : 05 Декабрь 2014, 16:47:22 »

Цитировать
auto_ptr в своем конструкторе забирает владение этим объектом и при выходе за область видимости (в своем деструкторе) освобождает память, так что с этой стороны все ок.

Спасибо.

Цитировать
std::auto_ptr _return1 (new TMemoryStream());
Image1->Bitmap->SaveToStream(_return1.get());

А функция get() вообще что делает? Она всегда должна возвращать кусок памяти куда указывает auto_ptr? Правильно?

Цитировать
Только функцию сохранения надо немного изменить - после создания auto_ptr необходимо дополнительно проверить на нулевой указатель

Эмбаркодеровцы не доработали пример.
Этот пример был мною замечен прямо в RADXE7 на стартовой странице студии (см.рис.).


Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


Re: new->auto_ptr
« Ответ #5 : 05 Декабрь 2014, 20:23:09 »

Цитата: SilverFish от 05 Декабрь 2014, 16:47:22
А функция get() вообще что делает? Она всегда должна возвращать кусок памяти куда указывает auto_ptr? Правильно?

get() возвращает указатель, хранящийся внутри "умного" указателя (смарт-пойнтера) типа auto_ptr, unique_ptr, shared_ptr и т.п. Эти классы из стандартной библиотеки - всего лишь шаблонные обертки вокруг обычных указателей. Реализация у auto_ptr примерно такая:

Код
template class T>
class auto_ptr
{
private:
 T* ptr;
public:
 auto_ptr(T* AObj): ptr(AObj) { }    // конструктор с присваиванием (забирает владение объектом)
 auto_ptr() : ptr(0) { }                    // конструктор по умолчанию
 ~auto_ptr() { delete ptr; }             // деструктор - удаление объекта из памяти
 
 T* get() { return ptr; }                  // возвращает внутренний объект
 void reset(T* AObj)                       // замена объекта
 {
    delete ptr; ptr = AObj;
 }
};
 

Цитата: SilverFish от 05 Декабрь 2014, 16:47:22
Эмбаркодеровцы не доработали пример.
Этот пример был мною замечен прямо в RADXE7 на стартовой странице студии (см.рис.).

  
Записан
SilverFish
Участник


Сказали спасибо: +14/-6
Offline

Сообщений: 784


« Ответ #6 : 06 Декабрь 2014, 19:06:13 »

Большое спасибо.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  




....

Powered by SMF 1.1.21 | SMF © 2025, Simple Machines
Страница сгенерирована за 0.054 секунд. Запросов: 19.