Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Уничтожение динамических объектов

2.1K
26 апреля 2010 года
smoki
115 / / 05.11.2006
Здравствуйте Уважаемые! Обращаюсь к Вам не столько за помощью сколько за консультацией.

Использую динамически созданные компоненты. Все функции по созданию описаны в классе.
Собственно код:
Код:
class ObjectItems
 {
  private:
    TTabSheet *Tab;
    TButton *But;
    TMemo *M1,*M2;
  public:
    void AddTab(AnsiString Caption);
    void AddMemo();
    void AddButton();

   ObjectItems()
    {
      Tab = NULL;
      But = NULL;
      M1 = NULL;
      M2 = NULL;
    }
   ~ObjectItems()
    {
      M1->Free();
      M2->Free();
      But->Free();
      Tab->Free();
    }
 };
 void ObjectItems::AddTab(AnsiString Caption)
  {
    static int num = 0;
    num++;
    TTabSheet *tab = new TTabSheet(this);
    tab->Caption = Caption;
    tab->Name = "Tab"+IntToStr(num);
    tab->PageControl = Form1->PageControl1;
    ObjectItems::Tab = tab;
  }
 void ObjectItems::AddMemo()
  {
   if(ObjectItems::Tab)
    {
      static int num = 0;
      num++;
      TMemo *memo = new TMemo (this);
      memo->Parent = ObjectItems::Tab;
      if(!ObjectItems::M1) ObjectItems::M1 = memo;
        else ObjectItems::M2 = memo;
    }

  }
 void ObjectItems::AddButton()
  {
    if(ObjectItems::Tab)
    {
      static int num = 0;
      num++;
      TButton* but = new TButton(this);
      but->Parent = ObjectItems::Tab;
      ObjectItems::But = but;
    }
  }


TList *list = new TList;

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   ObjectItems *a = new ObjectItems;
   a->AddTab("Строка");
   a->AddMemo();
   list->Add(a);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
   ObjectItems *a;
   a = static_cast<ObjectItems*>(list->Items[list->Count-1]);
   a->~ObjectItems();
   list->Delete(list->Count-1);
}


Дак вот, все работает так как надо, НО я заметил, что при таком использовании, память занятая не освобождается, хотя объекты уничтожаются в деструкторе, при долгом использовании, память довольно сильно забивается.
Работаю с классами недавно так что не ругайте сильно. В инете ничего толкового не нашел по деструкторам и объектам.
Заранее Спасибо! :)
11
26 апреля 2010 года
oxotnik333
2.9K / / 03.08.2007
метод Free в C++ нельзя использовать, это наследие от паскаля (к стати в справке об этом написано), он не вызывает деструктор объекта, отсюда и утечки памяти. Для освобождения памяти необходимо использовать delete.
62K
30 июля 2010 года
PoReX
4 / / 30.07.2010
Цитата: oxotnik333
метод Free в C++ нельзя использовать, это наследие от паскаля (к стати в справке об этом написано), он не вызывает деструктор объекта, отсюда и утечки памяти. Для освобождения памяти необходимо использовать delete.


Удаляю объекты вот таким способом:

 
Код:
Application->CreateForm(__classid(TAddressForm), &AddressForm);
    delete AddressForm;
    AddressForm=NULL;

и что-то память никак не уменьшается, почему?
5
30 июля 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: PoReX
и что-то память никак не уменьшается, почему?



Как измеряешь?

11
30 июля 2010 года
oxotnik333
2.9K / / 03.08.2007
Цитата: hardcase
Как измеряешь?


Как, как, в диспетчере задач. как еще можно то ;)

5
30 июля 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: oxotnik333
Как, как, в диспетчере задач.

Бгг

Цитата: oxotnik333
как еще можно то ;)

Перегрузкой new и delete с подсчетом количества.

11
30 июля 2010 года
oxotnik333
2.9K / / 03.08.2007
Цитата: hardcase
Бгг Перегрузкой new и delete с подсчетом количества.


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

1
31 июля 2010 года
kot_
7.3K / / 20.01.2000
Цитата: oxotnik333
Ну это из обрасти фантастики. Нем более что у автора new не используется.


Используется.

Код:
...
private:
    TTabSheet *Tab;
    TButton *But;
    TMemo *M1,*M2;
...
  void ObjectItems::AddTab(AnsiString Caption)
  {
    static int num = 0;
    num++;
    TTabSheet *tab = new TTabSheet(this);
    tab->Caption = Caption;
    tab->Name = "Tab"+IntToStr(num);
    tab->PageControl = Form1->PageControl1;
    ObjectItems::Tab = tab;
  }

А не уменьшается - потому что нигде не чистится. Удаление формы не удаляет объекты.
5
01 августа 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: kot_
Используется.

Оксотник имел в виду тот факт, что ТС не использует этот подход.

1
01 августа 2010 года
kot_
7.3K / / 20.01.2000
Ну как не использует? Он создает объекты при помощи new.
11
01 августа 2010 года
oxotnik333
2.9K / / 03.08.2007
Цитата: hardcase
Оксотник имел в виду тот факт, что ТС не использует этот подход.


Только не ТС, а второй вопрошающий PoReX

1
01 августа 2010 года
kot_
7.3K / / 20.01.2000
У вас что тоже жарко?
Мозги плавятся? Поливайтесь водичкой.
Не ужели так трудно посмотреть в тему, вместо того что бы всякую фигню писать?
11
01 августа 2010 года
oxotnik333
2.9K / / 03.08.2007
Цитата: kot_
Поливайтесь водичкой.


[off]
она у нас воняет :) пруфлинк
[/off]

287
01 августа 2010 года
Shiizoo
958 / / 14.03.2004
вот страна! xD
1
02 августа 2010 года
kot_
7.3K / / 20.01.2000
Цитата: oxotnik333
[off]
она у нас воняет :) пруфлинк
[/off]


[off]
мда. ну тогды конешно понятно. Но в принципе об этом еще Лермонтов писал:

Цитата:
Прощай немытая Россия,
Страна рабов, страна господ.
И вы мундиры голубые,
И ты им преданный народ...


А щас даже за стеной Кавказа скрыться не реально - свое нымытое рыло путинка сует повсюду.
Хотя у вас там как оказалось есть еще комсомольцы:

[QUOTE=vlksm]Вода в стандарте пью все время из под крана,запаха нет.[/QUOTE]

хуле. судя по подписи парниша из запоя уж который год не выходит - какой уж там запах.
[/off]
Вобщем ты имел ввиду что второй поциент не использует new?
Но на самом деле это не принципиально - память все равно будет чистится - ведь во первых выделение происходит при вызове CreateForm по сути вызывается именно он - это раз. А второе - указатель на форму является глобальным. И это важно. Поэтому у него и не происходит очистки памяти - он забыл убрать форму из Auto-create в Available. Можешь сам проверить.
Первый кстати тоже вполне получит такие же бока. У него указатель может переопределятся произвольное количество раз - а предыдущий объект никто нужным удалять не считает.

287
02 августа 2010 года
Shiizoo
958 / / 14.03.2004
Седня воды купить питьевой негазированной в кинотеатре на окраине москвы - 150 рублей. =) "Чистейшая вода из альп" написано. Нахрена она нам тут. ^_^ Понятно, что все погано, но не решение. :)
62K
02 августа 2010 года
PoReX
4 / / 30.07.2010
Цитата: kot_

Вобщем ты имел ввиду что второй поциент не использует new?
Но на самом деле это не принципиально - память все равно будет чистится - ведь во первых выделение происходит при вызове CreateForm по сути вызывается именно он - это раз. А второе - указатель на форму является глобальным. И это важно. Поэтому у него и не происходит очистки памяти - он забыл убрать форму из Auto-create в Available. Можешь сам проверить.
Первый кстати тоже вполне получит такие же бока. У него указатель может переопределятся произвольное количество раз - а предыдущий объект никто нужным удалять не считает.



Создаваемая форма находится в Available. Т.е. нужно сделать ее локальной? Память проверяю через диспетчер задач.

11
02 августа 2010 года
oxotnik333
2.9K / / 03.08.2007
Если напрягает рост памяти (по диспетчеру задач) можно просто скидывать резервы системы:
 
Код:
SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1);

после удаления указателя формы.
1
02 августа 2010 года
kot_
7.3K / / 20.01.2000
Цитата: PoReX
Создаваемая форма находится в Available. Т.е. нужно сделать ее локальной? Память проверяю через диспетчер задач.


Значит причина утечек не в этом коде вероятнее всего. Хотя я например предпочитаю использовать локальные указатели и вызывать явно new.
У меня приведенный ниже код очищает память полностью:

 
Код:
Application->CreateForm(__classid(TForm2), &Form2);
 Form2->ShowModal();
 delete Form2;
 Form2 = NULL;

Ищи меморилики в других местах. Либо на создаваемой форме у тебя находится компонент требующий дополнительных шагов для закрытия. Либо ты привел не весь код (а в чем смысл создания и сразу же удаления?) и у тебя гдето происходит переопределение указателя.
62K
02 августа 2010 года
PoReX
4 / / 30.07.2010
Цитата: kot_

У меня приведенный ниже код очищает память полностью:
 
Код:
Application->CreateForm(__classid(TForm2), &Form2);
 Form2->ShowModal();
 delete Form2;
 Form2 = NULL;


Даже этот код в новом проекте не очищает. Только 100Кб освобождаются после закрытия формы. По крайней мере в диспетчере так.

Цитата: kot_

Ищи меморилики в других местах. Либо на создаваемой форме у тебя находится компонент требующий дополнительных шагов для закрытия.


Пробовал сначала удалить все компоненты, а потом форму - эффект тот же.

Цитата: kot_

.....(а в чем смысл создания и сразу же удаления?) .....


Там в конструкторе ShowModal() стоит.

Вот ниже мой код

1
02 августа 2010 года
kot_
7.3K / / 20.01.2000
Ну во первых, я бы тебе посоветовал узнать больше о волшебном слове this, о инициализации полей класса и обращаться в методах класса к его полям либо только по имени, либо используя this. Конструкция вида AddressForm->Height тем более в конструкторе - недопустима и имеет проблемы - несмотря на то, что бидлер это "хавает".
Я бы возможно сделал бы замечания по архетектуре приложения - но принципиальных ошибок вроде нет. Как нет и утечек памяти. Памяти освобождается ровно столько, сколько и выделяется - рост объема памяти для приложения связан с системными механизмами оптимизации.
Все это с одной оговоркой - я тестировал проект под 6 билдером - соотвественно под студией могут быдь немного другие проблемы.
1
02 августа 2010 года
kot_
7.3K / / 20.01.2000
Как сбросить резервируемую для процесса память - выше показано.
62K
03 августа 2010 года
PoReX
4 / / 30.07.2010
Спасибо за советы, буду разбираться.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог