[PATCH 4/4] Fix all leak-at-exit from singletons in Subsurface

Thiago Macieira thiago at macieira.org
Sat Nov 30 09:18:04 UTC 2013


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 at macieira.org>
---
 gettextfromc.cpp                       |  4 ++--
 qt-ui/about.cpp                        |  3 ++-
 qt-ui/completionmodels.cpp             |  5 +++--
 qt-ui/divecomputermanagementdialog.cpp |  2 +-
 qt-ui/diveplanner.cpp                  |  4 ++--
 qt-ui/downloadfromdivecomputer.cpp     |  2 +-
 qt-ui/models.cpp                       | 16 ++++++++--------
 qt-ui/preferences.cpp                  |  3 ++-
 qt-ui/printdialog.cpp                  |  3 ++-
 qt-ui/simplewidgets.cpp                |  8 ++++----
 qt-ui/simplewidgets.h                  |  4 ++--
 qt-ui/subsurfacewebservices.cpp        |  5 +++--
 12 files changed, 32 insertions(+), 27 deletions(-)

diff --git a/gettextfromc.cpp b/gettextfromc.cpp
index fc11847..ba8158c 100644
--- a/gettextfromc.cpp
+++ b/gettextfromc.cpp
@@ -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)
diff --git a/qt-ui/about.cpp b/qt-ui/about.cpp
index 29abf63..4bf87df 100644
--- a/qt-ui/about.cpp
+++ b/qt-ui/about.cpp
@@ -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;
 }
diff --git a/qt-ui/completionmodels.cpp b/qt-ui/completionmodels.cpp
index 31733ad..ed1699a 100644
--- a/qt-ui/completionmodels.cpp
+++ b/qt-ui/completionmodels.cpp
@@ -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);
diff --git a/qt-ui/divecomputermanagementdialog.cpp b/qt-ui/divecomputermanagementdialog.cpp
index 883c8e9..af27e91 100644
--- a/qt-ui/divecomputermanagementdialog.cpp
+++ b/qt-ui/divecomputermanagementdialog.cpp
@@ -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;
 }
diff --git a/qt-ui/diveplanner.cpp b/qt-ui/diveplanner.cpp
index b18f56b..a80ae68 100644
--- a/qt-ui/diveplanner.cpp
+++ b/qt-ui/diveplanner.cpp
@@ -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)
diff --git a/qt-ui/downloadfromdivecomputer.cpp b/qt-ui/downloadfromdivecomputer.cpp
index e7f6552..95582ef 100644
--- a/qt-ui/downloadfromdivecomputer.cpp
+++ b/qt-ui/downloadfromdivecomputer.cpp
@@ -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;
 }
diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp
index b8909da..a3e1dcf 100644
--- a/qt-ui/models.cpp
+++ b/qt-ui/models.cpp
@@ -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
@@ -1755,8 +1755,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()
diff --git a/qt-ui/preferences.cpp b/qt-ui/preferences.cpp
index 4a31893..5a1a2a5 100644
--- a/qt-ui/preferences.cpp
+++ b/qt-ui/preferences.cpp
@@ -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;
 }
diff --git a/qt-ui/printdialog.cpp b/qt-ui/printdialog.cpp
index cf20864..5d5f727 100644
--- a/qt-ui/printdialog.cpp
+++ b/qt-ui/printdialog.cpp
@@ -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;
 }
diff --git a/qt-ui/simplewidgets.cpp b/qt-ui/simplewidgets.cpp
index 006e790..4f2b277 100644
--- a/qt-ui/simplewidgets.cpp
+++ b/qt-ui/simplewidgets.cpp
@@ -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*)));
diff --git a/qt-ui/simplewidgets.h b/qt-ui/simplewidgets.h
index c924370..e2ad195 100644
--- a/qt-ui/simplewidgets.h
+++ b/qt-ui/simplewidgets.h
@@ -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;
 };
 
diff --git a/qt-ui/subsurfacewebservices.cpp b/qt-ui/subsurfacewebservices.cpp
index b0e2ed7..eab7eb9 100644
--- a/qt-ui/subsurfacewebservices.cpp
+++ b/qt-ui/subsurfacewebservices.cpp
@@ -1,5 +1,6 @@
 #include "subsurfacewebservices.h"
 #include "../webservice.h"
+#include "mainwindow.h"
 
 #include <libxml/parser.h>
 #include <zip.h>
@@ -196,7 +197,7 @@ void WebServices::resetState()
 
 SubsurfaceWebServices* SubsurfaceWebServices::instance()
 {
-	static SubsurfaceWebServices *self = new SubsurfaceWebServices();
+	static SubsurfaceWebServices *self = new SubsurfaceWebServices(mainWindow());
 	self->setAttribute(Qt::WA_QuitOnClose, false);
 	return self;
 }
@@ -432,7 +433,7 @@ out:
 
 DivelogsDeWebServices* DivelogsDeWebServices::instance()
 {
-	static DivelogsDeWebServices *self = new DivelogsDeWebServices();
+	static DivelogsDeWebServices *self = new DivelogsDeWebServices(mainWindow());
 	self->setAttribute(Qt::WA_QuitOnClose, false);
 	return self;
 }
-- 
1.7.11.7



More information about the subsurface mailing list