Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.07.2012, 21:46   #1
Rangok
Пользователь
 
Регистрация: 30.07.2012
Сообщений: 13
По умолчанию Очень долгое освобождение динамически выделенной памяти

У меня есть отображение, в котором хранятся указатели на абстрактный класс Node
Код:
typedef  map <int num ,Node*> NodeCont;
.

Код:
//Абстрактный класс узла
class Node
{
public:
    virtual ~Node()=0;
////
....
////
};
При работе программы создаются объекты классов-потомков класса Node (Node1, Node2, Node12) с помощью new, и в NodeCont заносятся указатели на них (всего заносится около 80 тысяч элементов).
Код:

typedef set<NodeCont::iterator,CompareObj> LinksCont;

//Узел 1
class Node1:virtual public Node
{
protected:
     LinksCont next_links;
public:
    ~Node1(){}
////
....
////
};


//Узел 2
class Node2:virtual public Node
{
protected:
     LinksCont prev_links;
public:
    ~Node1(){}
////
....
////
};

//Узел 12
class Node12:private Node1,public Node2
{
public:
    ~Node12(){}
////
....
////
};
Размеры контейнеров типа LinksCont в узлах Node1, Node2, Node12- небольшие, в среднем 2-3 элемента.

После наполнения отображения программа выполняет различные действия с этими объектами.
При завершении работы программы освобождается память, выделенная для объектов.
Код:
    NodeCont::iterator iter=nodes.begin();
    NodeCont::iterator iter_end=nodes.end();
    while(iter!=iter_end)
    {
        //удаляем узел
        delete (*iter).second;
        ++iter;
    }
Тут и начинаются проблемы. Освобождение памяти занимает огромное время - раз в 100 большее, чем на работу всей программы (включая создание этого отображения).
В чем может быть проблема, как ускорить освобождение памяти?
Rangok вне форума Ответить с цитированием
Старый 31.07.2012, 10:11   #2
Last
В прострации
Форумчанин
 
Регистрация: 13.01.2009
Сообщений: 239
По умолчанию

Можно попробовать метод clear для map.
Цитата:
map::clear
void clear ( );
Clear content
All the elements in the container are dropped: their destructors are called, and then they are removed from the container, leaving it with a size of 0.
Интернет тупИт, удалите пожалуйста этот пост.
Пол-жизни сидючи, в монитор глядючи...

Последний раз редактировалось Stilet; 31.07.2012 в 15:44.
Last вне форума Ответить с цитированием
Старый 31.07.2012, 13:05   #3
Rangok
Пользователь
 
Регистрация: 30.07.2012
Сообщений: 13
По умолчанию

Цитата:
Сообщение от Last Посмотреть сообщение
Можно попробовать метод clear для map.
Это не поможет, скорость удаления будет та же самая.

На сколько я понял, проблема состоит в дефрагментации динамической памяти при создании объектов через new.
Может быть лучшим решением будет создать свою кучу для занесения в нее объектов Node1 , Node2 ,Node12 (при завершении работы освободить разом всю память из кучи)?

Последний раз редактировалось Rangok; 31.07.2012 в 14:23.
Rangok вне форума Ответить с цитированием
Старый 31.07.2012, 13:32   #4
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2Rangok
приведи минимальный, самодостаточный код, на котором проявляется проблема
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 31.07.2012, 14:07   #5
Krok27
Форумчанин
 
Аватар для Krok27
 
Регистрация: 08.07.2010
Сообщений: 505
По умолчанию

А зачем чисто виртуальный деструктор?

Цитата:
public:
virtual ~Node()=0;
Может:
Код:
   public:
    virtual ~Node(){}
Ежели хочется удалять через базовый класс.
Знающий не говорит, говорящий не знает (С) Лао Цзы
Krok27 вне форума Ответить с цитированием
Старый 31.07.2012, 14:22   #6
Rangok
Пользователь
 
Регистрация: 30.07.2012
Сообщений: 13
По умолчанию

Цитата:
Сообщение от pproger Посмотреть сообщение
2Rangok
приведи минимальный, самодостаточный код, на котором проявляется проблема
Проблема проявляется при удалении элементов, а код вот:
Код:
    NodeCont::iterator iter=nodes.begin();
    NodeCont::iterator iter_end=nodes.end();
    while(iter!=iter_end)
    {
        //удаляем узел
        delete (*iter).second;
        ++iter;
    }
Или вас интересует как создаются элементы Node1 Node2 И Node12?
Цитата:
Сообщение от Krok27 Посмотреть сообщение
А зачем чисто виртуальный деструктор?
Базовый класс абстрактный, в нем не содерижтся никаких данных, зачем ему свой деструктор?

Кстати если использовать удаление элементов в обратном порядке, то скорость удаления значительно возрастает (раз в 10)
Код:
    NodeCont::reverse_iterator iter=nodes.rbegin();
    NodeCont::reverse_iterator iter_end=nodes.rend();
    while(iter!=iter_end)
    {
        //удаляем узел
        delete (*iter).second;
        ++iter;
    }
Rangok вне форума Ответить с цитированием
Старый 31.07.2012, 15:06   #7
Krok27
Форумчанин
 
Аватар для Krok27
 
Регистрация: 08.07.2010
Сообщений: 505
По умолчанию

Цитата:
зачем ему свой деструктор
Что бы не писать в каждом наследуемом классе свой пустой деструктор )))). Все деструкторы вызываются по цепочке, а если нет тела деструктора, тогда что вызывается?

Чисто виртуальный деструктор нужен, по моему, для того что бы не забыть переопределить его в наследниках, но и тело у него должно быть.
Знающий не говорит, говорящий не знает (С) Лао Цзы

Последний раз редактировалось Krok27; 31.07.2012 в 15:26.
Krok27 вне форума Ответить с цитированием
Старый 31.07.2012, 15:25   #8
plgrm44
Пользователь
 
Регистрация: 29.05.2012
Сообщений: 23
По умолчанию

попробуйте замерить время в сборке-релизе, в дебаг-сборке при уничтожении памяти много лишних действий может быть(типа всяких проверок и логирований)
plgrm44 вне форума Ответить с цитированием
Старый 31.07.2012, 15:46   #9
Rangok
Пользователь
 
Регистрация: 30.07.2012
Сообщений: 13
По умолчанию

Цитата:
Сообщение от Krok27 Посмотреть сообщение
Что бы не писать в каждом наследуемом классе свой пустой деструктор )))). Все деструкторы вызываются по цепочке, а если нет тела деструктора, тогда что вызывается?

Чисто виртуальный деструктор нужен, по моему, для того что бы не забыть переопределить его в наследниках, но и тело у него должно быть.
То есть я могу написать в базовом классе ~Node(){}, а в классах потомках вообще не писать деструкторов?

Цитата:
Сообщение от plgrm44 Посмотреть сообщение
попробуйте замерить время в сборке-релизе, в дебаг-сборке при уничтожении памяти много лишних действий может быть(типа всяких проверок и логирований)
А поподробнее можно? Применительно к Microsoft Visual Studio или QtCreator.
Rangok вне форума Ответить с цитированием
Старый 31.07.2012, 15:47   #10
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

Rangok

Тут и начинаются проблемы. Освобождение памяти занимает огромное время - раз в 100 большее, чем на работу всей программы (включая создание этого отображения).
В чем может быть проблема, как ускорить освобождение памяти?


Код кривой. 80k элементов - это ни о чём.
http://liveworkspace.org/code/cb2109...27981718ce5f94

Искать кривизну, исправлять её. задействовать отладчик и профайлер.
Rififi вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
освобождение динамически выделенной памяти Einsttein Общие вопросы C/C++ 9 26.05.2010 15:40
Освобождение памяти Seran4ek Общие вопросы Delphi 7 21.12.2009 18:07
Освобождение памяти PUH Помощь студентам 1 22.11.2009 17:14
Освобождение памяти VadEr Общие вопросы Delphi 2 17.04.2009 22:23
Освобождение памяти AlexandrSid Общие вопросы Delphi 3 02.02.2009 13:45