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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> auto_ptr, утечка памяти 
:(
    Опции темы
lv151
Дата 26.6.2009, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



std::auto_ptr<...> tmp(new ...);

Detected memory leaks!
Dumping objects ->
c:\dir : {70} normal block at 0x01062828, 164 bytes long.

Возможно это? Или внутри типа утечка?
PM MAIL   Вверх
jonie
Дата 26.6.2009, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

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



автоуказатели не гарантируют отсутвия течей. Может течь внутри класса - запросто, а может еще где-то. Есть инструменты вроде valgring - умеют показывать "кто плохой". Попробуйте.


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
maxim1000
Дата 26.6.2009, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

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



а ещё стоит обратить вниманием на предупреждения
бывают случаи, когда std::auto_ptr не вызывает деструкторы: когда при его использовании доступно только объявление класса, как типа, без внутренностей
в таких случаях компилятор (по крайней мере, VC++ 2005) выдаёт предупреждение "деструктор не будет вызван"


--------------------
qqq
PM WWW   Вверх
586
Дата 26.6.2009, 23:44 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(lv151 @  26.6.2009,  18:25 Найти цитируемый пост)
std::auto_ptr<...> tmp(new ...);

Там случайно не "operator new []"?
PM   Вверх
lv151
Дата 27.6.2009, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



нет
PM MAIL   Вверх
Леопольд
Дата 27.6.2009, 10:46 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(lv151 @ 26.6.2009,  17:25)
std::auto_ptr<...> tmp(new ...);

Не помню где, но где-то точно, читал что комитет по стандартизации не рекомендует auto_ptr к использованию. Могу порекомендовать воспользоваться boost::shared_ptr.

Это сообщение отредактировал(а) Леопольд - 27.6.2009, 10:47


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
zim22
Дата 27.6.2009, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

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



Цитата(Леопольд @  27.6.2009,  10:46 Найти цитируемый пост)
Не помню где, но где-то точно

Майерс в каждом втором совете об этом пишет smile


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


Шустрый
*


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

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



Цитата(zim22 @  27.6.2009,  10:53 Найти цитируемый пост)
Майерс в каждом втором совете об этом пишет

Повторяется smile 
PM MAIL   Вверх
hsilgos
Дата 27.6.2009, 17:33 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

Не помню где, но где-то точно, читал что комитет по стандартизации не рекомендует auto_ptr к использованию. Могу порекомендовать воспользоваться boost::shared_ptr.

Цитата

Майерс в каждом втором совете об этом пишет 

Почему не использовать его для автоудаления объекта после выхода за пределы области видимости? boost::shared_ptr несколько тяжеловесный для этого.

lv151, 
Если не желаешь пользоваться профилировщиком, попробуй измени объект (создай в нем, в к примеру, массив-член класса char-ов на 10000 элементов. )
Если строчка
Цитата

 c:\dir : {70} normal block at 0x01062828, 164 bytes long.

изменится, значит, это твой объект не удаляется.
PM MAIL   Вверх
Леопольд
Дата 27.6.2009, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(hsilgos @ 27.6.2009,  17:33)
Почему не использовать его для автоудаления объекта после выхода за пределы области видимости? boost::shared_ptr несколько тяжеловесный для этого.

А std::auto_ptr не слишком "тяжёлый" для этой задачи? smile Можно просто воспользоваться самописным...
Код

template<class T>
class auto_delete{
private:
   auto_delete(const auto_delete<T>&) throw();
   auto_delete<T>& operator= (const auto_delete<T>&) throw();
   T *const wrapped_ptr;
public:
   explicit auto_delete(T *const ptr)throw():wrapped_ptr(ptr){
   }
   ~auto_delete() throw(){
      delete this->wrapped_ptr;
   }
   T *const operator->(void) const throw(){
       return this->wrapped_ptr;
   }
   T& operator*(void) const throw(){
       return *this->wrapped_ptr;
   }
};

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

Проблема, насколько я помню, в том что std::auto_ptr передаёт владение объектом, и может передать "владение" временному std::autp_ptr (например, если аргумент функции передаётся по значению...) после "смерти" которого автоудалится "завёрнутый" объект.

Это сообщение отредактировал(а) Леопольд - 28.6.2009, 00:52


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Леопольд
Дата 27.6.2009, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(lv151 @ 26.6.2009,  17:25)
std::auto_ptr<...> tmp(new ...);

Detected memory leaks!
Dumping objects ->
c:\dir : {70} normal block at 0x01062828, 164 bytes long.

Возможно это? Или внутри типа утечка?

Ещё хотелось бы добавить что причина скорее всего не в auto_ptr а в неправильном его применнии. Вот пример утечки. Знаете почему здесь утечка?
Код

class Interface{
public:
   virtual void calculate(void) throw() = 0;
};

class Implementor: public Interface{
private:
   int array[1024];
public:
    void calculate(void) throw(){}
};

//где-то в какой-то функции
{
...
   std::auto_ptr<Interface> ptr(new Implementor);
...
}


Это сообщение отредактировал(а) Леопольд - 27.6.2009, 21:20


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
mes
Дата 27.6.2009, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



...Удалено по просьбе Леопольда...

Это сообщение отредактировал(а) mes - 27.6.2009, 23:17


--------------------
PM MAIL WWW   Вверх
Леопольд
Дата 27.6.2009, 23:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes @ 27.6.2009,  21:27)
...

 smile Вопросы с подвохом позволяют прощупать глубину знаний лучше чем без него. smile

Удалите, пожалуйста, ответ, пока топикпастер не увидел...

Это сообщение отредактировал(а) Леопольд - 27.6.2009, 23:12


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
hsilgos
Дата 28.6.2009, 00:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

А std::auto_ptr не слишком "тяжёлый" для этой задачи?  Можно просто воспользоваться самописным...

Вот специально влез в STL и посмотрел. Вся его реализация - один приватный указатель и несколько легких методов, каждый из которых компилируется, только если реальная нужда в них есть.
boost::shared_ptr состоит как минимум из переменной и указателя. (На самом деле там еще внутренняя структура).

Цитата

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

Иногда объект A принимает указатель на другой объект B, который потом уничтожает сам. Этот объект нужно создать в куче и настроить:
Цитата

void g()
{
    //....
    if(!something)
        throw("ololo");
    //....
}


void f()
{
  A a;
  B *b = new B();
  
   b->set1(1);
  //....
  if( !something1 )
     return; // черт, забыли про объект

  //....
   b->set2("2");

   //....
   if( !something2 )
        throw(); // черт, опять забыли про объект
   //....
   g(); // во блин, а мы не знали про исключение или его небыло изначально и т.п...
   //....

  a.setB(b);
}

Все проблемы устраняются одним std::auto_ptr.
Пример ни разу не надуманный.

Это сообщение отредактировал(а) hsilgos - 28.6.2009, 00:19
PM MAIL   Вверх
Леопольд
Дата 28.6.2009, 01:57 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(hsilgos @ 28.6.2009,  00:18)
Цитата

А std::auto_ptr не слишком "тяжёлый" для этой задачи?  Можно просто воспользоваться самописным...

Вот специально влез в STL и посмотрел. Вся его реализация - один приватный указатель и несколько легких методов, каждый из которых компилируется, только если реальная нужда в них есть.
boost::shared_ptr состоит как минимум из переменной и указателя. (На самом деле там еще внутренняя структура).

Ладно, он не тяжёлый. Всё скорее всего встроится в место вызова. Как и в случае с моим кустарным классом, который, как минимум прозрачен а накатал я его за 5-10 минут. В его имени так же не содержится сокращённое слово pointer. smile Сразу хочу заметить, что тем, кто рассчитывает только лишь на "некривое" использование их кода, не стоит писать библиотек массового потребления. Некоторые пассатижами забивают гвозди. Сам видел, да и забивал тоже smile

Я не пользуюсь auto_ptr по причине его неинтуитивности. Думаю все согласятся что следующий код не выглядит ошибочным (если знать только то, что auto_ptr "подчищает хвосты"), но это не так:
Код

    std::auto_ptr<int> ptr0(new int);
    std::auto_ptr<int> ptr1(new int);
//    ...
    std::auto_ptr<int> ptr2;
//    ...
    ptr2 = ptr0;
//    ...
    ptr2 = ptr1; // как минимум, утечка памяти.

Это и есть его основная проблемма.


Если мне понадобится автоуборка то я лучше напишу вот так:
Код

template<class T>
class auto_delete{
private:
   auto_delete(const auto_delete<T>&) throw();
   auto_delete<T>& operator= (const auto_delete<T>&) throw();
   T *const wrapped_ptr;
public:
   auto_delete(T *const ptr)throw():wrapped_ptr(ptr){
   }
   ~auto_delete() throw(){
      delete this->wrapped_ptr;
   }
};
//    ...
void g()
{
    //...
    if(!something)
        throw("ololo");
    //...
}


void f()
{
  A a;
  B* b = new B();
  auto_delete<B> cleaner(b);
  
   b->set1(1);
  //....
  if( !something1 )
     return; 

  //....
   b->set2("2");

   //....
   if( !something2 )
        throw();
   //....
   g();
   //....

  a.setB(b);
}



Цитата
Цитата

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

Иногда объект A принимает указатель на другой объект B, который потом уничтожает сам. Этот объект нужно создать в куче и настроить:

Либо объект действительно большой и в стек никак не влезет (100 мегабайт, например), либо используется глубокая рекурсия (хотя здесь я этого не увидел), и таких объектов может быть очень много. Ещё есть смысл создавать объекты в куче, если ты пишешь "фабрику", но это не наш случай... Если же размер такого локального объекта пару сотен килобайт (а может и пару мегабайт), то я лучше увеличу размер стека. Конечно, всё это при условии, что функция вызывается достаточно часто, что-бы это имело смысл.

Это сообщение отредактировал(а) Леопольд - 28.6.2009, 02:13


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
hsilgos
Дата 28.6.2009, 02:15 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код


   std::auto_ptr<int> ptr0(new int);
    std::auto_ptr<int> ptr1(new int);
//    ...
    std::auto_ptr<int> ptr2;
//    ...
    ptr2 = ptr0;
//    ...
    ptr2 = ptr1; // как минимум, утечка памяти.


Не будет утечки памяти. Тут будет следующая коснтрукция:

Код

ptr2.reset(ptr1.release());



Цитата

Если мне понадобится автоуборка то я лучше напишу вот так:

Ну конечно, лучше использовать свой велосипед. Он ведь свой, родной  smile 

Цитата

Видимо объект большой. Ещё есть смысл создавать объекты в куче, если ты пишешь "фабрику", но это не наш случай...

Да нет же... Вот, к примеру, в wxWidgets есть набор классов для работы с XML.
Там документ можно и нужно создавать статически, а "ветви" ему уже нужно подсовывать созданные в куче. Он их затем сам удаляет.
И многие вещи так работают: иерархии классов окошечных классов во многих гуишных библиотеках и пр...
PM MAIL   Вверх
Леопольд
Дата 28.6.2009, 02:27 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



удалил чтоб' не позориться... smile


Это сообщение отредактировал(а) Леопольд - 28.6.2009, 02:43


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
hsilgos
Дата 28.6.2009, 02:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код

Modify(ptr);        // сразу видно что здесь memory leak?

Да с чего ж вы решили, что здесь будет меморилик? Не будет.
Объект класса Modify возьмет владение объектом и при завершении функции благополучно освободит память.

Код

ptr->AnyMember();  // интуитивно понятно в чём здесь ошибка?

Ну, для этого нужны минимальные знания о том, что при срабатывании конструтора копирования или оператора = передается владение другому объекту.

Добавлено через 1 минуту и 52 секунды
Я ведь не говорю о тотальном использовании shared_ptr ? Каждому инструменту - своё место. shared_ptr - у место для простейшего автоосвобождения.
PM MAIL   Вверх
Леопольд
Дата 28.6.2009, 02:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(hsilgos @ 28.6.2009,  02:15)
Код


   std::auto_ptr<int> ptr0(new int);
    std::auto_ptr<int> ptr1(new int);
//    ...
    std::auto_ptr<int> ptr2;
//    ...
    ptr2 = ptr0;
//    ...
    ptr2 = ptr1; // как минимум, утечка памяти.


Не будет утечки памяти. Тут будет следующая коснтрукция:

Код

ptr2.reset(ptr1.release());



Цитата

Если мне понадобится автоуборка то я лучше напишу вот так:

Ну конечно, лучше использовать свой велосипед. Он ведь свой, родной  smile 

Ошибся, утечки не будет. Но я уверен что тот кто это написал бы smile не ожидает что это удалит объект, изначально выделенный на ptr0...

Дело в том что это не велосипед, и даже не педаль от него. Они сложнее устроены... Можно разобраться в auto_ptr, а можно использовать свой примитив. На самом деле, второй вариант даже быстрее и меньше шансов что поймёшь его немножко неправильно. smile

Добавлено @ 02:42
Цитата(hsilgos @ 28.6.2009,  02:37)
Код

Modify(ptr);        // сразу видно что здесь memory leak?

Да с чего ж вы решили, что здесь будет меморилик? Не будет.
Объект класса Modify возьмет владение объектом и при завершении функции благополучно освободит память.

Что то я и правда туплю... :(

Добавлено @ 02:42
Но всё равно, auto_ptr работает не интуитивно! smile

Добавлено @ 02:47
Цитата(hsilgos @ 28.6.2009,  02:15)
Да нет же... Вот, к примеру, в wxWidgets есть набор классов для работы с XML.
Там документ можно и нужно создавать статически, а "ветви" ему уже нужно подсовывать созданные в куче. Он их затем сам удаляет.
И многие вещи так работают: иерархии классов окошечных классов во многих гуишных библиотеках и пр...

Это не те функции которые вызываются 90% времени работы программы, я прав? smile

Это сообщение отредактировал(а) Леопольд - 28.6.2009, 09:33


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
hsilgos
Дата 28.6.2009, 02:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

Но всё равно, auto_ptr работает не интуитивно! 

Что да, то да. Я его и не использую для серьезных задач.
Однако чтобы не плодить try/catch и не копипастить освобождение ресурсов во всех точках выхода из функции auto_ptr работает замечательно.
И для его успешного применения достаточно знать минимум: передача владения и reset/release.
Кода становится меньше и понятнее. Несмотря на неочевидность auto_ptr  smile 
PM MAIL   Вверх
Леопольд
Дата 28.6.2009, 02:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(hsilgos @ 28.6.2009,  02:37)
Добавлено @ 02:39
Я ведь не говорю о тотальном использовании shared_ptr ? Каждому инструменту - своё место. shared_ptr - у место для простейшего автоосвобождения.

Наверное Вы имели ввиду всё же auto_ptr
Я теперь вообще не понимаю как у него может быть утечка памяти из-за auto_ptr... Тут больше похоже что утечка из-за класса, завёрнутого в auto_ptr.




--------------------
вопросов больше чем ответов
PM MAIL   Вверх
hsilgos
Дата 28.6.2009, 02:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

Наверное Вы имели ввиду всё же auto_ptr

да, спать уже пора. Голова думает одно, а руки по-привычке набирают другое smile 

Это сообщение отредактировал(а) hsilgos - 28.6.2009, 03:00
PM MAIL   Вверх
mes
Дата 28.6.2009, 10:23 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(Леопольд @  28.6.2009,  01:40 Найти цитируемый пост)
Можно разобраться в auto_ptr, а можно использовать свой примитив.

Если у своего примитива та же политика удаления, то писать его еще менее интуитивно, 
так как вместо того чтоб использовать общеизвестный инструмент, у которого есть документация, Вы предлагаете отвлекать программиста на написание/изучение "примитива".
Даже если это и занимает 5 минут - лучше потратить это время на изучение std::auto_ptr. 
Или вас не устраивает название ? так на крайний случай просто замените имя : typedef std::auto_ptr  auto_delete
(хотя это тоже путь в сторону)

Цитата(Леопольд @  28.6.2009,  01:40 Найти цитируемый пост)
    std::auto_ptr<int> ptr2;
//    ...
    ptr2 = ptr0;

Не нравятся такие конструкции ? правильно. Но это не проблема auto_ptr, a программиста который такое написал smile




--------------------
PM MAIL WWW   Вверх
Леопольд
Дата 28.6.2009, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes @ 28.6.2009,  10:23)
Цитата(Леопольд @  28.6.2009,  01:40 Найти цитируемый пост)
    std::auto_ptr<int> ptr2;
//    ...
    ptr2 = ptr0;

Не нравятся такие конструкции ? правильно. Но это не проблема auto_ptr, a программиста который такое написал smile

Честно говоря, я не понял о чём речь...

Добавлено @ 18:54
Цитата(mes @ 28.6.2009,  10:23)
Цитата(Леопольд @  28.6.2009,  01:40 Найти цитируемый пост)
Можно разобраться в auto_ptr, а можно использовать свой примитив.

Если у своего примитива та же политика удаления, то писать его еще менее интуитивно, 
так как вместо того чтоб использовать общеизвестный инструмент, у которого есть документация, Вы предлагаете отвлекать программиста на написание/изучение "примитива".
Даже если это и занимает 5 минут - лучше потратить это время на изучение std::auto_ptr.

Дело в том что этот примитив запрещает копирование и т.д. Т.е. программист не сможет использовать его не по назначению - авто чистка памяти. Им нельзя пользоваться как указателем, это примитивный уборщик мусора. Мне кажется что этого описания достаточно для безошибочного использования. Конечно, при условии что программист понимает как создаются и разрушаются локальные объекты. А вот с auto_ptr надо помнить что нельзя с ним делать, а что можно. Это конечно не проблема, но всё равно, лучше помнить что-то другое smile
Время, которе будет потрачено на осмысление его функции измеряется в секундах. Это писал я его 5 минут... smile

Это сообщение отредактировал(а) Леопольд - 28.6.2009, 20:20


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
bsa
Дата 28.6.2009, 23:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Почему нельзя что-то делать с auto_ptr? Можно! Более того, я так понимаю, он и создан для этого.
Код
std::auto_ptr<MyClass> myClassCreator()
{
   std::auto_ptr<MyClass> pMyClass;
   ...
   pMyClass.reset(new MyClassDerived);
   ...
   return pMyClass;
}

...

myClassCreator(); //результат не используем, но и утечки не будет

std::auto_ptr<MyClass> pMyClass = myClassCreator();
...
pMyClass = myClassCreator(); //опять утечки нет
Просто у каждого инструмента свое назначение. Проблема только в том, что документацию никто не читает. И не запоминает главных особенностей. С другой стороны, у этого шаблона есть недостаток при таком использовании - неочевидность. Лично я его использую именно как авто-освобождение и удобный менеджер объектов. Т.е. я делаю reset не заботясь о том, содержит автопоинтер что-то или нет.
Кстати, по моему в boost есть более подходящая вещь - scoped_ptr. Я правда не изучал его, но подозреваю, что это то, что нужно.

Это сообщение отредактировал(а) bsa - 28.6.2009, 23:41
PM   Вверх
Леопольд
Дата 29.6.2009, 07:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(bsa @ 28.6.2009,  23:40)
Почему нельзя что-то делать с auto_ptr? Можно! Более того, я так понимаю, он и создан для этого.
...
Кстати, по моему в boost есть более подходящая вещь - scoped_ptr. Я правда не изучал его, но подозреваю, что это то, что нужно.

Никто не говорит что нельзя. Можно пользоваться MFC а не wxWidgets (предположим что целевая платформа исключительно Win), но на мой взгляд wxWidgets лучше спроектирован и удобнее в использовании. Дело вкуса.

Я тоже так думаю, что для целей авточистки можно найти что-то более подходящее чем auto_ptr... smile

Добавлено через 14 минут и 8 секунд
scoped_ptr (scoped_array) действительно то что надо. Он делает то-же самое что и мой кустарный класс, только больше smile К тому же, есть документация...


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
lv151
Дата 29.6.2009, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



auto_ptr советует использовать Брюс Эккель.
И вобще, смысл пихать в stl auto_ptr если он лажа?


Это сообщение отредактировал(а) lv151 - 29.6.2009, 10:47
PM MAIL   Вверх
zim22
Дата 29.6.2009, 10:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

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



Цитата(lv151 @  29.6.2009,  10:46 Найти цитируемый пост)
auto_ptr советует использовать Брюс Эккель.

из учебника "Философия С++"? страницу не подскажите?


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


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

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



не поленился перенабрать с книжки "Язык программирования С++. Вводный курс. 4 издание" (Липпман)
smile
Ограничения класса auto_ptr
Шаблон класса auto_ptr предоставляет удобный и безопасный способ работы с объектами, размещенными в динамически распределенной памяти. Чтобы правильно использовать класс auto_ptr, следует жестко придерживаться ограничений, которые налагает этот класс.
  • Не используйте класс auto_ptr для хранения указателя на статический объект. В противном случае, при удалении объекта класса auto_ptr, он попытается удалить указатель на объект, размещенный не в динамической памяти, что приведет к непредсказуемым последствиям.
  • Никогда не используйте два объекта класса auto_ptr для хранения адреса того же объекта. Как правило, эта ошибка происходит в случае, Когда тот же указатель используется ри инициализации двух разных объектов класса auto_ptr или применении функции reset(). Эту ошибку можно совершить косвенно, при использовании результата выполнения функции get() одного объекта класса auto_ptr при инициализации другого, или при его передаче функции reset() другого объекта класса auto_ptr
  • Не используйте объект класса auto_ptr для хранения указателя на массив в динамически распределяемой памяти. При удалении объекта классса auto_ptr он использует обычный оператор delete (который освободит только первый элемент массива), а не оператор delete[], способный удалить весь массив.
  • Не сохраняйте объекты класса auto_ptr в контейнере. Контейнеры требуют, чтобы классы хранимых в них объектов обладали функциями копирования и присвоения, которые ведут себя аналогично функциям встроенных типов. После копирования (или присвоения) оба объекта должны иметь одинаковое значение. Класс auto_ptr этому требования не удовлетворяет.



--------------------
PM MAIL   Вверх
lv151
Дата 29.6.2009, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(zim22 @  29.6.2009,  10:50 Найти цитируемый пост)
из учебника "Философия С++"? страницу не подскажите? 

Практическое программирование, с 40.

PM MAIL   Вверх
Alexeis
Дата 29.6.2009, 11:58 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Цитата(lv151 @  29.6.2009,  09:46 Найти цитируемый пост)
auto_ptr советует использовать Брюс Эккель.
И вобще, смысл пихать в stl auto_ptr если он лажа?

  Использовать везде и всегда будет неправильным. Это всего одна из стратегий владения, когда один владеет, он же и уничтожает, при этом владелец должен уничтожаться последним. auto_ptr удобен при передаче объекта как посылки, как сообщения другому объекту. Т.е. передал объект вместе с правами владения или вернул из функции с правами владения. Он не годиться в случае если время жизни объекта заранее не определено и имеются несколько ссылок на него. При использовании auto_ptr "просто так", всегда есть шанс что сделаешь прямое присвоение объектов и потеряешь экземпляр. 
  


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
lv151
Дата 29.6.2009, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Проблема вот в чём.

Код

class MyClass
{
private:
    IInterface1* in1;
    IInterface2* in2;
public:
    MyClass1()
    {
          in1 = new MyClass1;
          in2= new MyClass2;
    }

    ~MyClass1()
    {
          delete in1;
          delete in2;
    }

}


Удаляются только указатели на функции, но адреса in1, in2 нет.

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


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

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



Цитата(lv151 @  29.6.2009,  16:29 Найти цитируемый пост)
Удаляются только указатели на функции, но адреса in1, in2 нет.

Может быть утечка памяти по причине того, что деструктор в классах IInterface2 и IInterface1 невиртуальные (так как обьекты удаляются по указателю базового класса).
PM   Вверх
Lazin
Дата 29.6.2009, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



еще здесь есть неявно созданные конструктор копирования и оператор присваивания, при вызове которых произойдет утечка памяти
PM MAIL Skype GTalk   Вверх
Леопольд
Дата 29.6.2009, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(lv151 @ 29.6.2009,  10:46)
auto_ptr советует использовать Брюс Эккель.
И вобще, смысл пихать в stl auto_ptr если он лажа?

Обратная совместимость. Нельзя что-то просто убрать из STL если это уже там есть. Кстати, книжку он в каком году написал? smile

И я не говорил что он лажа. Просто при работе с ним надо быть осторожным, а где-то он наверняка может оказаться полезным, ну а в STL контейнерах его просто нельзя использовать. Со scoped_ptr/_array не надо быть таким осторожным. shared_ptr идеально подходит для STL контейнеров... Их наверняка можно использовать криво, правда для этого уже надо будет извратиться... скорее всего smile Я не хочу над этим раздумывать, пустая трата времени, но сходу придумать, как их подломать, не могу.

Добавлено @ 17:27
Цитата(Lazin @ 29.6.2009,  16:37)
еще здесь есть неявно созданные конструктор копирования и оператор присваивания, при вызове которых произойдет утечка памяти

Здесь не только утечка, ещё и undefined behaviour может быть из-за MyClass::MyClass(const MyClass&); и MyClass& MyClass::operator= (const MyClass&); Например, при передаче по значению как аргумент функции, память (видимо частично) будет освобождена, после смерти этой копии. Потом она будет освобождена ещё ровно столько раз, сколько копий объекта было создано.

А на вопрос (27.6.2009, 21:19) так и нет ответа, к сожалению. 

Это сообщение отредактировал(а) Леопольд - 29.6.2009, 17:51


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Леопольд
Дата 29.6.2009, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(lv151 @ 29.6.2009,  16:29)
Проблема вот в чём.
...

Для того чтобы понять в чём ещё проблема, кроме не объявленного оператора присваивания и конструктора копирования по умолчанию, надо посмотреть на объявления IInterface1 и IInterface2

Добавлено @ 17:47
Цитата(Леопольд @ 29.6.2009,  17:15)
Их наверняка можно использовать криво, правда для этого уже надо будет извратиться... скорее всего smile Я не хочу над этим раздумывать, пустая трата времени, но сходу придумать, как их подломать, не могу.

Я случайно придумал!!! smile
Код

Class* lptr = new Class;
boost::shared_ptr<Class> ptr(lptr);
delete lptr;

Не каждый додумается так непреднамеренно ошибиться. Если только с очень большого бодуна. А если не пьёт, то шансы почти нулевые smile

Это сообщение отредактировал(а) Леопольд - 29.6.2009, 17:55


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Alexeis
Дата 29.6.2009, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Цитата(Леопольд @  29.6.2009,  16:36 Найти цитируемый пост)
Я случайно придумал!!!

А еще можно явно вызвать деструктор статического или временного объекта smile
Собственно для того и придумали чтобы можно было писать так
Код

boost::shared_ptr<Class> ptr(new Class);

Зачем иметь 2е переменные в одной области видимости? 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Леопольд
Дата 29.6.2009, 19:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Не смог успокоится и придумал простейший сборщик мусора. Вроде неплохо получилось. Критика приветсвуется! Но пожалуйста, без грубости, помягче... smile
Код
moved


Создал отдельную тему http://forum.vingrad.ru/forum/act-ST/f-92/...2/unread-1.html

Это сообщение отредактировал(а) Леопольд - 29.6.2009, 20:16


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.1216 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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