Название: Qt+valgrind
Отправлено: Hellenna от Март 28, 2005, 01:00
Господа, помогите разобраться. Известно, что Qt сама особождает память, т.е. в деструкторе класса, производного от клсса из qt не надо делать delete. Никогда с этим не возникало проблем. А недавно я столкнулась со следующим:
#include <qdialog.h> #include <qlayout.h> #include <qobject.h> #include <qpushbutton.h> #include <qcombobox.h> #include <qlabel.h> #include <qlineedit.h> #include <qtabwidget.h> #include <qstring.h> #include <qstringlist.h> #include <qdir.h> #include <qtextbrowser.h>
class Config : public QDialog { Q_OBJECT; public: Config( QWidget* parent = 0, const char* name = 0 ); ~Config(); ... private: ... QString *cod_name, *dics_path, *home, *s; QStringList *cod_list1; QDir *dir; .... };
Config::Config( QWidget* parent, const char* name ) : QDialog( parent, name ) { tabWidget = new QTabWidget( this, "tabWidget" ); tab1 = new QWidget( tabWidget, "tab1" ); tabWidget->insertTab( tab1, tr("Configure") );
//*******ЗДЕСЬ УТЕКАЕТ ПАМЯТЬ*********** dics_path = new QString('\0'); cod_name = new QString('\0'); s = new QString('\0'); cod_list1 = new QStringList(); dir = new QDir(); //**************************************
layout1 = new QHBoxLayout( 0, 0, 6, "layout1"); spacer4 = new QSpacerItem( 40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); layout1->addItem( spacer4 );
...
} Config::~Config(){}
Причем, память утекает только в выделенном куске, и до и после него тоже есть динамическое выделение, но там все в порядке. От чего это может быть?
Название: Re: Qt+valgrind
Отправлено: Zigmar от Март 28, 2005, 01:42
Господа, помогите разобраться. Известно, что Qt сама особождает память, т.е. в деструкторе класса, производного от клсса из qt не надо делать delete. Никогда с этим не возникало проблем. Это не правильно, и если вы так считали, то проблеммы скоре всего были, но остались незамеченные. Во-первых в классе Qt вообще нет никакой функциональности, а все Qt-шные классы от него наследуют чтоб включить все константы и enums, т.е. как своебразная замета namespace-ов. Во-вторых, Qt освобождает память только у объектов которые наследуют от класса QObject и только если этому объекту указали объект-родитель (parent). Тогда родительский объект, при уничтожение, уничтожит все дочерние объекты - например какое-нибудь окно при уничтожение, удаляет все виджеты которые содержит. Если-же объекту не дали родителя, то удалять его будет некому, и это ответственность пользователя его удалить. В-третих, насчет вашего примера кода: [list=1] - QString и QDir не наследуют от QObject, соотвественно это целиком и полностью ваша отвественность их удалить.
- Не имеет смысла хранить объекты QString по ссылке. Это во-первых просто неудобно, во-вторых потенциальный источник целой кучи ошибок с выделением/освобождением памяти, и наконец это практически не быстрее чем работа с QString-ами по значению. Дело в том что QString использует "implicit sharing" (см. документацию) что позволяет очень эффективно копировать/передвавать объекты.
- Вообще всё что можно создавать на стеке - лучше создавать на стеке, и избавить себя от кучи головной боли и ошибок. Потому уже узкие места можно съоптимизировать, если они будет работать недостаточно быстро. Единственное что никогда нельзья делать - это создавать да стеке QObject-ы с указанным родителем - это гарантированная ошибка, так как такой объект попытаются удалить дважды - один раз при выходе из зоны видимости, а второй раз при одаление родительского объекта.
- Если динамическое выделение всё-же необходимо, то стоит воспользоваться каким-нибудь smart pointer-ом, который бы сам занимался освобождением памяти, например boost::shared_ptr или в более простых вариантвх std::auto_ptr.
[/list:o]
Удачи.
Название: Re: Qt+valgrind
Отправлено: Hellenna от Март 28, 2005, 10:50
Во-первых в классе Qt вообще нет никакой функциональности, а все Qt-шные классы от него наследуют чтоб включить все константы и enums, т.е. как своебразная замета namespace-ов.
Я имела в ввиду, не класс Qt, а все классы в библиотеке qt. Во-вторых, Qt освобождает память только у объектов которые наследуют от класса QObject Спасибо. не знала этого. Теперь понятно. Не имеет смысла хранить объекты QString по ссылке. Это во-первых просто неудобно, во-вторых потенциальный источник целой кучи ошибок с выделением/освобождением памяти, и наконец это практически не быстрее чем работа с QString-ами по значению. Дело в том что QString использует "implicit sharing" (см. документацию) что позволяет очень эффективно копировать/передвавать объекты.
я обычно так и делаю, но тот код писала не я.... - Вообще всё что можно создавать на стеке - лучше создавать на стеке, и избавить себя от кучи головной боли и ошибок. Потому уже узкие места можно съоптимизировать, если они будет работать недостаточно быстро. Единственное что никогда нельзья делать - это создавать да стеке QObject-ы с указанным родителем - это гарантированная ошибка, так как такой объект попытаются удалить дважды - один раз при выходе из зоны видимости, а второй раз при одаление родительского объекта.
- Если динамическое выделение всё-же необходимо, то стоит воспользоваться каким-нибудь smart pointer-ом, который бы сам занимался освобождением памяти, например boost::shared_ptr или в более простых вариантвх std::auto_ptr.
Удачи. Еще раз спасибо за советы.
|