Fix all leak-at-exit from singletons in Subsurface

Subsurface creates a lot of singleton instances on demand, but nothing
ever deleted them. Since they are singletons, these memory allocations
are technically not leaks. However, they clutter the output in valgrind
and other memory analysers, hiding the real issues.

The solution is to delete these items at exit. For the models and for
gettextFromC, the solution is to use a QScopedPointer, which will delete
its payload when it gets destroyed. For the dialogs and other widgets,
we can't do that: they need to be deleted before QApplication exits, so
we just set the parent in all of them to the main window.

Signed-off-by: Thiago Macieira <thiago@macieira.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Thiago Macieira 2013-11-30 09:18:04 -08:00 committed by Dirk Hohndel
parent bd7ded8894
commit b22f1da59e
12 changed files with 32 additions and 27 deletions

View file

@ -17,8 +17,8 @@ void gettextFromC::reset(void)
gettextFromC* gettextFromC::instance()
{
static gettextFromC *self = new gettextFromC();
return self;
static QScopedPointer<gettextFromC> self(new gettextFromC());
return self.data();
}
extern "C" const char *trGettext(const char *text)

View file

@ -1,5 +1,6 @@
#include "about.h"
#include "ssrf-version.h"
#include "mainwindow.h"
#include <QDebug>
#include <QDialogButtonBox>
#include <QNetworkReply>
@ -7,7 +8,7 @@
SubsurfaceAbout *SubsurfaceAbout::instance()
{
static SubsurfaceAbout *self = new SubsurfaceAbout();
static SubsurfaceAbout *self = new SubsurfaceAbout(mainWindow());
self->setAttribute(Qt::WA_QuitOnClose, false);
return self;
}

View file

@ -1,11 +1,12 @@
#include "completionmodels.h"
#include "dive.h"
#include "mainwindow.h"
#define CREATE_SINGLETON(X) \
X* X::instance() \
{ \
static X* self = new X(); \
return self; \
static QScopedPointer<X> self(new X()); \
return self.data(); \
}
CREATE_SINGLETON(BuddyCompletionModel);

View file

@ -23,7 +23,7 @@ void DiveComputerManagementDialog::init()
DiveComputerManagementDialog* DiveComputerManagementDialog::instance()
{
static DiveComputerManagementDialog *self = new DiveComputerManagementDialog();
static DiveComputerManagementDialog *self = new DiveComputerManagementDialog(mainWindow());
self->setAttribute(Qt::WA_QuitOnClose, false);
return self;
}

View file

@ -1104,8 +1104,8 @@ DivePlannerPointsModel::DivePlannerPointsModel(QObject* parent): QAbstractTableM
DivePlannerPointsModel* DivePlannerPointsModel::instance()
{
static DivePlannerPointsModel* self = new DivePlannerPointsModel();
return self;
static QScopedPointer<DivePlannerPointsModel> self(new DivePlannerPointsModel());
return self.data();
}
void DivePlannerPointsModel::setBottomSac(int sac)

View file

@ -37,7 +37,7 @@ namespace DownloadFromDcGlobal{
DownloadFromDCWidget *DownloadFromDCWidget::instance()
{
static DownloadFromDCWidget *dialog = new DownloadFromDCWidget();
static DownloadFromDCWidget *dialog = new DownloadFromDCWidget(mainWindow());
dialog->setAttribute(Qt::WA_QuitOnClose, false);
return dialog;
}

View file

@ -67,8 +67,8 @@ CylindersModel::CylindersModel(QObject* parent): current(0), rows(0)
CylindersModel *CylindersModel::instance()
{
static CylindersModel *self = new CylindersModel();
return self;
static QScopedPointer<CylindersModel> self(new CylindersModel());
return self.data();
}
static QVariant percent_string(fraction_t fraction)
@ -559,8 +559,8 @@ void WeightModel::setDive(dive* d)
WSInfoModel* WSInfoModel::instance()
{
static WSInfoModel *self = new WSInfoModel();
return self;
static QScopedPointer<WSInfoModel> self(new WSInfoModel());
return self.data();
}
bool WSInfoModel::insertRows(int row, int count, const QModelIndex& parent)
@ -680,8 +680,8 @@ void WSInfoModel::update()
TankInfoModel* TankInfoModel::instance()
{
static TankInfoModel *self = new TankInfoModel();
return self;
static QScopedPointer<TankInfoModel> self(new TankInfoModel());
return self.data();
}
const QString& TankInfoModel::biggerString() const
@ -1711,8 +1711,8 @@ Qt::ItemFlags GasSelectionModel::flags(const QModelIndex& index) const
GasSelectionModel* GasSelectionModel::instance()
{
static GasSelectionModel* self = new GasSelectionModel();
return self;
static QScopedPointer<GasSelectionModel> self(new GasSelectionModel());
return self.data();
}
void GasSelectionModel::repopulate()

View file

@ -1,11 +1,12 @@
#include "preferences.h"
#include "mainwindow.h"
#include <QSettings>
#include <QDebug>
#include <QFileDialog>
PreferencesDialog* PreferencesDialog::instance()
{
static PreferencesDialog *dialog = new PreferencesDialog();
static PreferencesDialog *dialog = new PreferencesDialog(mainWindow());
dialog->setAttribute(Qt::WA_QuitOnClose, false);
return dialog;
}

View file

@ -1,4 +1,5 @@
#include "printdialog.h"
#include "mainwindow.h"
#include <QDebug>
#include <QPushButton>
@ -7,7 +8,7 @@
PrintDialog *PrintDialog::instance()
{
static PrintDialog *self = new PrintDialog();
static PrintDialog *self = new PrintDialog(mainWindow());
self->setAttribute(Qt::WA_QuitOnClose, false);
return self;
}

View file

@ -106,7 +106,7 @@ void MinMaxAvgWidget::setMinimum(const QString& minimum)
RenumberDialog* RenumberDialog::instance()
{
static RenumberDialog* self = new RenumberDialog();
static RenumberDialog* self = new RenumberDialog(mainWindow());
return self;
}
@ -118,7 +118,7 @@ void RenumberDialog::buttonClicked(QAbstractButton* button)
}
}
RenumberDialog::RenumberDialog(): QDialog()
RenumberDialog::RenumberDialog(QWidget *parent): QDialog(parent)
{
ui.setupUi(this);
connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*)));
@ -126,7 +126,7 @@ RenumberDialog::RenumberDialog(): QDialog()
ShiftTimesDialog* ShiftTimesDialog::instance()
{
static ShiftTimesDialog* self = new ShiftTimesDialog();
static ShiftTimesDialog* self = new ShiftTimesDialog(mainWindow());
return self;
}
@ -150,7 +150,7 @@ void ShiftTimesDialog::buttonClicked(QAbstractButton* button)
}
}
ShiftTimesDialog::ShiftTimesDialog(): QDialog()
ShiftTimesDialog::ShiftTimesDialog(QWidget *parent): QDialog(parent)
{
ui.setupUi(this);
connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*)));

View file

@ -39,7 +39,7 @@ public:
private slots:
void buttonClicked(QAbstractButton *button);
private:
explicit RenumberDialog();
explicit RenumberDialog(QWidget *parent);
Ui::RenumberDialog ui;
};
@ -50,7 +50,7 @@ public:
private slots:
void buttonClicked(QAbstractButton *button);
private:
explicit ShiftTimesDialog();
explicit ShiftTimesDialog(QWidget *parent);
Ui::ShiftTimesDialog ui;
};

View file

@ -1,5 +1,6 @@
#include "subsurfacewebservices.h"
#include "../webservice.h"
#include "mainwindow.h"
#include <libxml/parser.h>
@ -44,7 +45,7 @@ void WebServices::hideUpload()
SubsurfaceWebServices* SubsurfaceWebServices::instance()
{
static SubsurfaceWebServices *self = new SubsurfaceWebServices();
static SubsurfaceWebServices *self = new SubsurfaceWebServices(mainWindow());
self->setAttribute(Qt::WA_QuitOnClose, false);
return self;
}
@ -269,7 +270,7 @@ static bool merge_locations_into_dives(void)
DivelogsDeWebServices* DivelogsDeWebServices::instance()
{
static DivelogsDeWebServices *self = new DivelogsDeWebServices();
static DivelogsDeWebServices *self = new DivelogsDeWebServices(mainWindow());
self->setAttribute(Qt::WA_QuitOnClose, false);
return self;
}