Russian Qt Forum

Qt => Установка, сборка, отладка, тестирование => Тема начата: MuLLIKA от Ноябрь 13, 2010, 02:55



Название: Ошибка удаления объекта класса
Отправлено: MuLLIKA от Ноябрь 13, 2010, 02:55
Доброго все здравия! У меня в программе много классов, у каждого из них есть свой деструктор в отором я описал удаление переменных из "кучи" (delete perem;)

Вопрос такой, почему при удалении переменной класса который описан мной, т.е переменная не стандартного класса Qt (допустим QComboBox *box;) компилятор выдает очень много предупреждений(waraning)

После того как я описал деструкторы по закрытию моей программы дебаггер выкидывает такую ошибку

inline QString::~QString() { if (!d->ref.deref()) free(d); }

Invalid Address specified to RtlFreeHeap( 003E0000, 6A2902C7 )

Буду очень признателен за помощь!
Зарание спасибо!


Название: Re: Ошибка удаления объекта класса
Отправлено: Пантер от Ноябрь 13, 2010, 08:25
Код в студию.


Название: Re: Ошибка удаления объекта класса
Отправлено: ufna от Ноябрь 13, 2010, 10:54
у меня есть подозрение что ты создаешь объект как

box = new QComboBox(this),

а потом для этого this создаешь деструктор, где убиваешь box ручками?


Название: Re: Ошибка удаления объекта класса
Отправлено: Пантер от Ноябрь 13, 2010, 11:29
ufna, у тебя сегодня libastral.so собралась?


Название: Re: Ошибка удаления объекта класса
Отправлено: BRE от Ноябрь 13, 2010, 13:48
у меня есть подозрение что ты создаешь объект как

box = new QComboBox(this),

а потом для этого this создаешь деструктор, где убиваешь box ручками?
Ну и что в этом плохого?


Название: Re: Ошибка удаления объекта класса
Отправлено: MuLLIKA от Ноябрь 13, 2010, 14:56
ufna, да именно так! а в чем здесь может быть проблема?

Пантер, код оч много. А пример выделения памяти для переменной и ее удаление ufna написал.


Название: Re: Ошибка удаления объекта класса
Отправлено: MuLLIKA от Ноябрь 13, 2010, 15:14
Вот такой деструктор
mainW::~mainW()
{
    //delete pTree;
    delete tool;
    //delete scene;
    //delete view;
    delete pix;
    delete device_but;
    delete cables_device;
    delete pButGr;
    //delete vw;
    delete mainMenu;
    delete StartSignal;
    delete exitProgram;
    delete StatusL;
    delete StatusL2;
    delete StatusL3;
    delete wgt;
    delete itemCables;
    delete itemWid;
    delete itemKT4;
    delete itemClear;
    delete but;
    delete widget;
}

на  delete pix; выкидывает ошибку

Объявление в h файле
private:
    QToolBox *tool;
    QGraphicsPixmapItem *pix;


Название: Re: Ошибка удаления объекта класса
Отправлено: Пантер от Ноябрь 13, 2010, 15:20
Покажи как создаешь pix.


Название: Re: Ошибка удаления объекта класса
Отправлено: MuLLIKA от Ноябрь 13, 2010, 15:26
Разобрался!

~mainW()
{
    if(!pix) delete pix;
}
я проверил, оказываеться что pix доходя до деструктора уже удалена(видимо автоматически), потому что ручками я не прописывал ничего


Название: Re: Ошибка удаления объекта класса
Отправлено: Пантер от Ноябрь 13, 2010, 15:38
Не всегда сработает. Т.к. pix может быть удален, но указатель не занулен.
Кто у него родитель?
И да, если назначаешь родителя, то удалять вручную не нужно, родитель сам это сделает.


Название: Re: Ошибка удаления объекта класса
Отправлено: ufna от Ноябрь 13, 2010, 16:11
Ну и что в этом плохого?

Ну это уже к Qt, а не ко мне. Как минимум пример выше "что в этом плохого".


Название: Re: Ошибка удаления объекта класса
Отправлено: ufna от Ноябрь 13, 2010, 16:12
ufna, у тебя сегодня libastral.so собралась?

давно уже основной инструмент. Предсказываю даже будущее.


Название: Re: Ошибка удаления объекта класса
Отправлено: BRE от Ноябрь 13, 2010, 16:21
Ну это уже к Qt, а не ко мне. Как минимум пример выше "что в этом плохого".
В Qt можно спокойно использовать delete для уничтожения объектов, даже если при их создании указывался parent.
Главное повторно не удалять уже удаленные объекты. Что кстати и показывает пример выше. Внимательно посмотри на код:
Код
C++ (Qt)
~mainW()
{
   if(!pix) delete pix; // Если pix == 0, вызываем delete 0; :)
}
 


Название: Re: Ошибка удаления объекта класса
Отправлено: ufna от Ноябрь 14, 2010, 16:45
BRE, дак я по-моему и не говорил, что удалять их нельзя :) Я говорил о том, что если нет необходимости удалять вручную и делаются вещи из разряда if(!pix) - то лучше отдать бразды правления Qt, правильно указывая родителей. К примеру при работе с сетевым менеджером можно легко прийти к косяку, где delete вручную будет вызывать падение :) Ну и самое место "граблей" будет в том, что частенько родители сменяются динамически при работе, к примеру айтемы, при добавлении в список и т.п. - и их удаление из "создающего" виджета тотальное - по-моему будет не айс. Вполне возможно здесь именно такая ситуация.

Ну а так то я совсем не против ручного delete и так далее :)


Название: Re: Ошибка удаления объекта класса
Отправлено: MuLLIKA от Ноябрь 15, 2010, 03:20
Спасибо мужики! но у меня возникла еще одна проблема. При удалении объекта со сцены мне бы хотелось освободить память которая выделилась на создание этого объекта. До сего момента у меня объект просто удалялся со сцены removeItem(..)
внутри самого объекта осуществдяеться удаление со сцены, а сейчас (может глупо) после удаления со сцены я делаю  delete this, вызывается деструктор, удаляються переменные и потом он выкидывает ошибку сегментации показывая на
inline T *data() const
    {
        return d;
    }

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


Название: Re: Ошибка удаления объекта класса
Отправлено: ufna от Ноябрь 15, 2010, 13:50
Приводи минимальный код с проблемой.


Название: Re: Ошибка удаления объекта класса
Отправлено: MuLLIKA от Ноябрь 15, 2010, 15:43
Есть 3 класса: class mainW : public QMainWindow, class SceneExm : public QGraphicsScene, class generaot4astot : public QMainWindow
в mainW делаеться scene = new SceneExm();
в SceneExm - GenerSc  = new generaot4astot(++GenerOnScene, this);
                    itemSc = new graphitemclass(graphitemclass::generator4ast_DT, GenerSc->sceneContextMenu, GenerSc);
Здесь на сцену добавляеться объект класса генератор. По щельчку правой кнопкой на объект вызываеться ф-ия удаления в классе генератора:
void generaot4astot::removeItem()
{
    QGraphicsItem *item;
    foreach (item, sc->selectedItems())
    {
        qgraphicsitem_cast<graphitemclass *>(item)->removeLines();
        sc->removeItem(item);
        sc->RemSc = this;

    }
//sc->removeItemGenerator(item, this);
    //this->~generaot4astot();
}
тут я пробую вызвать деструктор, по прохождению деструктора дебаггер выкидывает ошибку с ссылкой на строку в классе QScopedPointer(что то такое) 
inline T *data() const
    {
        return d;
    }
Но при выполнении программы, при удалении объекта ошибка не вылетает, но память не освобождаеться. (смотерл в диспетчере задач)


Название: Re: Ошибка удаления объекта класса
Отправлено: ufna от Ноябрь 17, 2010, 17:43
Брр, сделай проект с минимальным кодом для этой ошибки. А то сооовершенно непонятно ничего.

кстати, деструктор так вызывать не следует.


Название: Re: Ошибка удаления объекта класса
Отправлено: MuLLIKA от Ноябрь 18, 2010, 02:16
Я разобрался в чем проблема мне нужен поток который будет подчищять удаленые итемы со сцены.
Но возникла проблема...описал тут = http://www.prog.org.ru/topic_15739_0.html


Название: Re: Ошибка удаления объекта класса
Отправлено: Igors от Ноябрь 18, 2010, 12:20
Я разобрался в чем проблема мне нужен поток который будет подчищять удаленые итемы со сцены.
Это как "потушить пожар бензином"  :)

Если есть непонятки с удалением, перекройте деструктор удаляемого (если он еще не перекрыт), поставьте там точку останова и смотрите где и как его удаляют.  И пользуйтесь тегом для оформления кода, иначе читать Ваши посты неудобно.


Название: Re: Ошибка удаления объекта класса
Отправлено: ufna от Ноябрь 18, 2010, 17:11
Жуть О_о это даже хлеще чем тушить пожар бензином

Может все-таки сделаешь проект с ошибкой или выложишь исходники целиком?


Название: Re: Ошибка удаления объекта класса
Отправлено: MuLLIKA от Ноябрь 19, 2010, 18:41
Все сделал. суть в том что, есть итем(QGraphicsItem) который рисует полигон с катринкой генератора, есть класс generator, который создаетьбся вместе с этим итемом, итем добавляеться на сцену. Уэтого итема можно вызвать контекстное меню, его вызов прописан в классе итема (класс переписан мной), есть 2 значения меню "Удалить" и "Изменить параметры", так вот при удалени у еня итем просто убирался со сцены (removeItem(item)), а память выделенная под класс итема и класс генератора не освобождалась!Т.е. при добавлении других устройств на сцену занимаемая память становилась все больше и больше, а при удалении не освобождалась, поэтому утекала.
Нужно было сделать так что бы где удалялся родитель этих 2х классов, но проблема была в том то где сделать удаление родителя! потому что сама реализация контекстного меню была описанаа в классе генератора, т.е. при нажатии на итем на сцене шла обработка нажатия в классе итем, и вызывалось меню собранное в классе генератора, т.е. при удалении генератора нужно было сделать деилт родителя, но из класса генератора или из класса итема нельзя удалить родителя, потому что при удалении он удаляет своих "сыновей" (как Вы мне сказали, я это проверил), а это значит при удалении родителя допустим из класса генератора родитель удалит ЭТОТ класс генератора и выполнение программы не будет знать куда возвращаться после команды делит родителя, ибо указатель на класс в которой вызывался делит уже освобожден.
Об этом говорит вот это строка:
Код:
inline T *data() const
    {
        return d;
    }
Решил эту проблему через запуск потока в начале программы, который следит за удалением родителя этих 2х классов, того объекта который удаляют со сцены.
Спасибо, за помощь!