Considering the following code:
#include <iostream>
#include <QObject>
class ParentClass : public QObject
{
public:
explicit ParentClass(QObject *parent = nullptr) : QObject(parent) {
std::cout << "ParentClass" << std::endl;
}
~ParentClass() override {
std::cout << "~ParentClass" << std::endl;
}
};
class ChildClass : public QObject
{
public:
explicit ChildClass(QObject *parent = nullptr) : QObject(parent) {
std::cout << "ChildClass" << std::endl;
}
~ChildClass() override {
std::cout << "~ChildClass" << std::endl;
}
void hi() { std::cout << "hi" << std::endl; }
};
int main()
{
auto *parent = new ParentClass();
auto *child = new ChildClass(parent);
child->hi();
delete parent;
return 0;
}
When I run clang static analysis (scan-build
), it reports a potential memory leak:
main.cxx:34:3: warning: Potential leak of memory pointed to by 'child'
delete parent;
^~~~~~~~~~~~~
1 warning generated.
The issue is I am using Qt's memory management here, where the parent object on a tree structure manages the children. It works perfectly fine, as can be seen by the output:
ParentClass
ChildClass
hi
~ParentClass
~ChildClass
I can see that this is not obvious, but on the other hand I have a lot of code using Qt infrastructure, hence a big report full of false-positives.
The FAQ (https://clang-analyzer.llvm.org/faq.html) doesn't talk about memory leaks.
Is there a way to suppress these false-positives so they won't be reported?
All I could think of is to create some pretend code calling delete, but it would require changing a lot of code. And besides, it feels like a hack:
auto *parent = new ParentClass();
auto *child = new ChildClass(parent);
child->hi();
#ifdef __clang_analyzer__
delete child;
#endif
delete parent;
Is there a better way?
This is what I do to solve these warnings:
in my_utils.h:
in my_utils.cpp:
Then, in the code with the warning, I can just do something like:
For me, this is very tidy. And using #defines alloows me to change the method later if a better solution comes around.