Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Проблема с динамическим созданием/удалением объектов / 25 сообщений из 26, страница 1 из 2
09.10.2006, 18:11
    #34042612
Tubrik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
Задачей было найти потери памяти в проекте.

Причина оказалась вот в чем. Имеется шаблонный класс "Динамический список " или просто class_List , т.е. тип данных списка определяется шаблонно. Есть class_A , который создает объект class_List для хранения данных типа *class_Data . Класс class_List пользует new & delete для создания/удалени я своих элементов. Есть потомок от class_Data cl_child_Data .
Так вот один из потомков класса Class_A , загоняет в список объекты (исп. указатель на объект) не *class_Data , а *cl_child_Data , т.е. его потомка , что вполне допустимо. Но при очистке памяти оператором delete удаляется естественно предок (class_Data), а не наследник, который фактически туда помещен - отсюда и лики.

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

Можно ли как-нидь сделать "умный" delete, чтобы он сам "знал" какой тип объекта находится в памяти и грамотно удалял потомка, а не предка?
...
Рейтинг: 0 / 0
09.10.2006, 18:14
    #34042621
Проблема с динамическим созданием/удалением объектов
деструкторы class_Data, cl_child_Data должны быть виртуальные
...
Рейтинг: 0 / 0
09.10.2006, 18:19
    #34042635
KGP
KGP
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
Tubrik
Но при очистке памяти оператором delete удаляется естественно предок (class_Data), а не наследник, который фактически туда помещен - отсюда и лики.

Не пойму, что значит?
Список class_List самописный?
В cl_child_Data дестуктор виртуальный, переопределен нормально?
cl_child_Data выделяет память в ходе работы, в деструкторе она освобождается?
...
Рейтинг: 0 / 0
09.10.2006, 18:19
    #34042636
Tubrik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
Голенков Владимирдеструкторы class_Data, cl_child_Data должны быть виртуальные

очищает память class_List, но так как он удаляет данные типа class_Data, хотя хранит на самом деле cl_child_Data. Т.е. до деструктора cl_child_Data дело в любом случае не доходит, если я правильно понимаю.
...
Рейтинг: 0 / 0
09.10.2006, 18:26
    #34042653
Akh
Akh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
Tubrik Голенков Владимирдеструкторы class_Data, cl_child_Data должны быть виртуальные

очищает память class_List, но так как он удаляет данные типа class_Data, хотя хранит на самом деле cl_child_Data. Т.е. до деструктора cl_child_Data дело в любом случае не доходит, если я правильно понимаю.

Если ты сделаешь деструкторы виртальные, то указатель на объект твоего класса предка (созданного потомком) будет содержать виртуальную таблицу, в которой будет храниться деструктор потомка, который и вызовется.
...
Рейтинг: 0 / 0
09.10.2006, 18:29
    #34042665
Akh
Akh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
Еще вариант - удалять класс, приведенный к классу потомка

Код: plaintext
1.
delete ((class_child_Data*)class_Data);
...
Рейтинг: 0 / 0
09.10.2006, 18:31
    #34042677
Tubrik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
KGP Tubrik
Но при очистке памяти оператором delete удаляется естественно предок (class_Data), а не наследник, который фактически туда помещен - отсюда и лики.

Не пойму, что значит?
Список class_List самописный?
В cl_child_Data дестуктор виртуальный, переопределен нормально?
cl_child_Data выделяет память в ходе работы, в деструкторе она освобождается?

class_List самописный.

Он же и выделяет память под объекты и он же удаляет, к примеру:

class_Data *n = new class_Data();
n = [объект класса cl_child_Data];

а удаляется:

delete [как объект класса class_Data];
...
Рейтинг: 0 / 0
09.10.2006, 18:35
    #34042689
Tubrik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
AkhЕще вариант - удалять класс, приведенный к классу потомка

Код: plaintext
1.
delete ((class_child_Data*)class_Data);


так работает, но тут нельзя предсказать какой именно из потомков будет использован.
...
Рейтинг: 0 / 0
09.10.2006, 18:49
    #34042720
KGP
KGP
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
AkhЕще вариант - удалять класс, приведенный к классу потомка

Код: plaintext
1.
delete ((class_child_Data*)class_Data);

Да нельзя так ПРИНЦИПИАЛЬНО!

to Tubrik:
Я спрашивал деструктор виртуальный, переопределен?
скинь определение класса class_Data и cl_child_Data на уровне определения ( реализацию - деструкторов)
...
Рейтинг: 0 / 0
09.10.2006, 19:04
    #34042749
Tubrik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
KGP AkhЕще вариант - удалять класс, приведенный к классу потомка

Код: plaintext
1.
delete ((class_child_Data*)class_Data);

Да нельзя так ПРИНЦИПИАЛЬНО!

to Tubrik:
Я спрашивал деструктор виртуальный, переопределен?
скинь определение класса class_Data и cl_child_Data на уровне определения ( реализацию - деструкторов)

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

Деструктор не виртуальный и не переопределен.

Еще не могу понять, как тут может помочь деструктор объекта, если он ничего не должен удалять, а должен быть правильно удален сам объект cl_child_Data.

Наследование происходит не напрямую от class_Data, а через другие объекты.
...
Рейтинг: 0 / 0
09.10.2006, 20:04
    #34042834
KGP
KGP
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
Tubrik
Почему так нельзя ...

Дело вашенское, убеждать вас не буду.
ИМХО - виртуалить и переопределить деструктор, где и освобождать выделенную ранее этим инстансом память (не память под инстанс).
...
Рейтинг: 0 / 0
09.10.2006, 20:18
    #34042846
onstat-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
Tubrik KGP AkhЕще вариант - удалять класс, приведенный к классу потомка

Код: plaintext
1.
delete ((class_child_Data*)class_Data);

Да нельзя так ПРИНЦИПИАЛЬНО!

to Tubrik:
Я спрашивал деструктор виртуальный, переопределен?
скинь определение класса class_Data и cl_child_Data на уровне определения ( реализацию - деструкторов)

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


Потому, что в народе это называется "Закат солнца вручную".


Tubrik
Деструктор не виртуальный и не переопределен.

Еще не могу понять, как тут может помочь деструктор объекта, если он ничего не должен удалять, а должен быть правильно удален сам объект cl_child_Data.


В качестве отладки, вставьте во все конструкторы
fprintf(log, "Constructing object %x\n", this);
И в деструкторы
fprintf(log, "Destructing object %x\n", this);

Запустите программу и проверьте что(сколько) реально создается и что (сколько)реально удаляется.

Потом зделайте деструкторы виртуальными и сравните репорты.
...
Рейтинг: 0 / 0
10.10.2006, 09:53
    #34043304
Akh
Akh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
KGP AkhЕще вариант - удалять класс, приведенный к классу потомка

Код: plaintext
1.
delete ((class_child_Data*)class_Data);

Да нельзя так ПРИНЦИПИАЛЬНО!


Только если уверен. Есстественно, будет правельно с виртуальным диструктором, но так тоже не запрещается.
...
Рейтинг: 0 / 0
10.10.2006, 10:41
    #34043493
KGP
KGP
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
Akh
Только если уверен. Есстественно, будет правельно с виртуальным диструктором, но так тоже не запрещается.

Кем, кому запрещается?! ... я Вам и остальным (кроме своих подчиненных) разрешаю это Ваши проблемы.
...
Рейтинг: 0 / 0
10.10.2006, 10:46
    #34043515
Akh
Akh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
KGP Akh
Только если уверен. Есстественно, будет правельно с виртуальным диструктором, но так тоже не запрещается.

Кем, кому запрещается?! ... я Вам и остальным (кроме своих подчиненных) разрешаю это Ваши проблемы.

1. Вполне адекватное решение.
2. Молодец, что ж сказать.
...
Рейтинг: 0 / 0
10.10.2006, 13:25
    #34044182
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
Akh KGP

БРЭЙК...
прелесть плюсов - мона всё, или практически всё..Шаги к разумному каждый находит сам. В книгах ,либо из горького опыта.

Думаю стоит не цепляться за слова, а просто привести примеры...из жизни


(круглый)
...
Рейтинг: 0 / 0
10.10.2006, 13:58
    #34044327
Akh
Akh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
Разработанные, используемые в различных готовых и рабочих проектах различными разработчиками, плохо спроектированные с точки зрения расширяемости классы, которые необходимо использовать.
...
Рейтинг: 0 / 0
10.10.2006, 14:15
    #34044409
ZeusTheTrueGod
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
Библиотека STL подходить для использования списков,массивов,карт и так далее
Поскольку там всё реализовано на шаблонах, то доступен её исходный текст, где можно разоабраться как что происходит
...
Рейтинг: 0 / 0
10.10.2006, 18:10
    #34045301
Tubrik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
Полагаю, что поступил несколько глупо, т.к. коряво упростил схему классов, решив, что так легче будет объяснить. В результате вызвал ненужный спор и недразумения, да и сам запутался, чего конечно не хотел. Поэтому помещу в новой теме все "как есть".
...
Рейтинг: 0 / 0
10.10.2006, 18:16
    #34045323
Akh
Akh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
Да все здесь понятно. Надо использовать виртуальные деструкторы. Если это не возможно, то явное приведение типа.

Сравни 2 кода:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
class A{
   public:
      A() {printf("costr A\n");};
      ~A() {printf("distr A\n");};
}

class B : public A{
   public:
      B() {printf("costr B\n");};
      ~B() {printf("distr B\n");};
}

main () {
   A *a;
   a = new B();
   delete a;
}

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
class A{
   public:
      A() {printf("costr A\n");};
      virtual ~A() {printf("distr A\n");};
}

class B : public A{
   public:
      B() {printf("costr B\n");};
      virtual ~B() {printf("distr B\n");};
}

main () {
   A *a;
   a = new B();
   delete a;
}
...
Рейтинг: 0 / 0
10.10.2006, 18:31
    #34045390
Tubrik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
AkhДа все здесь понятно. Надо использовать виртуальные деструкторы. Если это не возможно, то явное приведение типа.


Т.е. если у объекта деструктор виртуальный, то delete удаляет объект на который указывает указатель, а если нет, то объект, тип которого задан при объявлении указателя?

Т.е. размер удаляемого объекта в delete зависит от виртуальности деструктора?
...
Рейтинг: 0 / 0
10.10.2006, 18:32
    #34045398
Gryz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
да
...
Рейтинг: 0 / 0
10.10.2006, 18:53
    #34045463
Tubrik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
еще маленький вопрос

//в коде есть такое...
classA *pCA;
pCA = new classA();
((class_child_A *)pCA )->add( new classB(this, ...) ); //это нормально?
.....
.....
...
Рейтинг: 0 / 0
10.10.2006, 18:57
    #34045471
Gryz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
Главное - это то что, у тебя в деструкторах обычно высвобождаются захваченные объектом ресурсы (например, память - при помощи new). Надо, чтоб вызвался правильный деструктор, который освободит захваченные ресурсы
...
Рейтинг: 0 / 0
10.10.2006, 20:31
    #34045626
blinded
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с динамическим созданием/удалением объектов
Tubrikеще маленький вопрос

//в коде есть такое...
classA *pCA;
pCA = new classA();
((class_child_A *)pCA )->add( new classB(this, ...) ); //это нормально?
.....
.....

а кто его знает? может у тебя где-нибудь опратор приведения к class_child_A*
спрятался. А вообще-то правильнее пользоваться .._cast<> операторами
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Проблема с динамическим созданием/удалением объектов / 25 сообщений из 26, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]