Russian Qt Forum
Май 03, 2024, 23:44 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Qt+valgrind  (Прочитано 8235 раз)
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(){}


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

От чего это может быть?
Записан
Zigmar
Гость
« Ответ #1 : Март 28, 2005, 01:42 »

Цитата: "Hellenna"
Господа, помогите разобраться.
Известно, что 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]

    Удачи.
Записан
Hellenna
Гость
« Ответ #2 : Март 28, 2005, 10:50 »

Цитата: "Zigmar"

Во-первых в классе Qt вообще нет никакой функциональности, а все Qt-шные классы от него наследуют чтоб включить все константы и enums, т.е. как своебразная замета namespace-ов.

Я имела в ввиду, не класс Qt, а все классы в библиотеке qt.
Цитата: "Zigmar"
Во-вторых, Qt освобождает память только у объектов которые наследуют от класса QObject

Спасибо. не знала этого. Теперь понятно.
Цитата: "Zigmar"

Не имеет смысла хранить объекты QString по ссылке. Это во-первых просто неудобно, во-вторых потенциальный источник целой кучи ошибок с выделением/освобождением памяти, и наконец это практически не быстрее чем работа с QString-ами по значению. Дело в том что QString использует "implicit sharing" (см. документацию) что позволяет очень эффективно копировать/передвавать объекты.

я обычно так и делаю, но тот код писала не я....
Цитата: "Zigmar"

  • Вообще всё что можно создавать на стеке - лучше создавать на стеке, и избавить себя от кучи головной боли и ошибок. Потому уже узкие места можно съоптимизировать, если они будет работать недостаточно быстро. Единственное что никогда нельзья делать - это создавать да стеке QObject-ы с указанным родителем - это гарантированная ошибка, так как такой объект попытаются удалить дважды - один раз при выходе из зоны видимости, а второй раз при одаление родительского объекта.
  • Если динамическое выделение всё-же необходимо, то стоит воспользоваться каким-нибудь smart pointer-ом, который бы сам занимался освобождением памяти, например boost::shared_ptr или в более простых вариантвх std::auto_ptr.


Удачи.

Еще раз спасибо за советы.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.046 секунд. Запросов: 20.