Модераторы: 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   Вверх
Страницы: (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.1108 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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