[utilities/krusader] app/UserAction: UserAction: Fix a memory leak
Toni Asensi Esteve <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit be0d1a7bcddf039f72ba839155e309896414e96a by Toni Asensi Esteve.
Committed on 16/08/2026 at 22:14.
Pushed by asensi into branch 'master'.
UserAction: Fix a memory leak
Revision: https://invent.kde.org/utilities/krusader/-/merge_requests/193
M +18 -0 app/UserAction/kraction.cpp
M +4 -1 app/UserAction/kraction.h
M +3 -0 app/UserAction/kractionbase.cpp
https://invent.kde.org/utilities/krusader/-/commit/be0d1a7bcddf039f72ba839155e309896414e96a
diff --git a/app/UserAction/kraction.cpp b/app/UserAction/kraction.cpp
index 13129187f..b2fe09c54 100644
--- a/app/UserAction/kraction.cpp
+++ b/app/UserAction/kraction.cpp
@@ -55,6 +55,12 @@ KrActionProcDlg::KrActionProcDlg(const QString &caption, bool enableStderr, QWid
, _stderr(nullptr)
, _currentTextEdit(nullptr)
{
+ // This dialog is intentionally used as a standalone top-level window rather
+ // than being owned through a QObject parent. Delete it as soon as the user
+ // closes it, any surviving external reference is a QPointer and will be
+ // reset automatically to nullptr
+ setAttribute(Qt::WA_DeleteOnClose);
+
setWindowTitle(caption);
setWindowModality(Qt::NonModal);
@@ -266,6 +272,10 @@ void KrActionProc::start(QStringList cmdLineList)
cmd = KrServices::quote(KDESU_PATH) + " -t -u " + _action->user() + " -c " + KrServices::quote(cmd);
}
MAIN_VIEW->terminalDock()->sendInput(cmd + '\n');
+ // This KrActionProc object was created on the heap in actionProcFactoryMethod().
+ // When the command is forwarded to the embedded terminal, no external QProcess
+ // is started here, therefore no later finished signal will call processExited()
+ // to destroy this KrActionProc object. Schedule its destruction now
deleteLater();
} else { // will start a new process
_proc = new KProcess(this);
@@ -280,6 +290,9 @@ void KrActionProc::start(QStringList cmdLineList)
QStringList termArgs = KShell::splitArgs(term, KShell::TildeExpand);
if (termArgs.isEmpty()) {
KMessageBox::error(nullptr, i18nc("Arg is a string containing the bad quoting.", "Bad quoting in terminal command:\n%1", term));
+ // This KrActionProc object was created on the heap in actionProcFactoryMethod().
+ // Because execution stops here and no later finished signal will call processExited()
+ // to destroy this KrActionProc object, schedule its destruction now
deleteLater();
return;
}
@@ -300,6 +313,9 @@ void KrActionProc::start(QStringList cmdLineList)
bool separateStderr = false;
if (_action->execType() == KrAction::CollectOutputSeparateStderr)
separateStderr = true;
+ // Create an unparented top-level output dialog. It deletes itself when it's closed
+ // (after that, `_output` must be checked before using it). `_output` is a QPointer,
+ // so it is reset automatically to nullptr when the dialog is destroyed
_output = new KrActionProcDlg(_action->text(), separateStderr);
// connect the output to the dialog
_proc->setOutputChannelMode(KProcess::SeparateChannels);
@@ -326,6 +342,8 @@ void KrActionProc::processExited(int /*exitCode*/, QProcess::ExitStatus /*exitSt
// TODO tell the user the program exit code
_output->slotProcessFinished();
}
+ // This KrActionProc object was created on the heap in actionProcFactoryMethod().
+ // It is destroyed here after the external process has finished
delete this; // banzai!!
}
diff --git a/app/UserAction/kraction.h b/app/UserAction/kraction.h
index 1d10185f6..7db9063a4 100644
--- a/app/UserAction/kraction.h
+++ b/app/UserAction/kraction.h
@@ -12,6 +12,7 @@
// QtCore
#include <QByteArray>
+#include <QPointer>
#include <QUrl>
// QtGui
#include <QFont>
@@ -256,7 +257,9 @@ private:
KProcess *_proc;
QString _stdout;
QString _stderr;
- KrActionProcDlg *_output;
+ // It's non-owning. It resets to nullptr when
+ // the dialog is destroyed (e.g. on close)
+ QPointer<KrActionProcDlg> _output;
};
#endif // KRACTION_H
diff --git a/app/UserAction/kractionbase.cpp b/app/UserAction/kractionbase.cpp
index 36539c4f1..6c1351528 100644
--- a/app/UserAction/kractionbase.cpp
+++ b/app/UserAction/kractionbase.cpp
@@ -69,5 +69,8 @@ void KrActionBase::handleError(const Error &err)
KrActionProc *KrActionBase::actionProcFactoryMethod()
{
+ // Create a KrActionProc object on the heap for this action. The caller
+ // must not delete the returned pointer because the KrActionProc object is
+ // responsible for destroying itself later
return new KrActionProc(this);
}