0

I am using Qt 5.7 for a GUI application with a QProgressBar. I suspect that there might be a memory leak since memory usage increases during runtime for about 50MB/s. I could narrow down the problem to one line of code.

QProgressBar *pbarQuality;
...
int curQuality = data.getQuality();
if (curQuality < 0) {
    curQuality = 0;
    qWarning("Value set to 0. ");
}
if (curQuality > 100) {
    curQuality = 100;
    qWarning("Value set to 100. ");
}
ui.pbarQuality->setValue(curQuality); //The memory problem doesn't occur when this single line is commented out

The value of the QProgressBar(pbarQuality) is only for displaying. It isn't used anywhere else.

I find this a very strange behaviour. Am I missing something?

Here is the auto generated code by the Qt Designer:

        pbarQuality = new QProgressBar(frame_5);
        pbarQuality->setObjectName(QStringLiteral("pbarQuality"));
        pbarQuality->setGeometry(QRect(10, 50, 130, 23));
        pbarQuality->setValue(24);
dcfyg
  • 75
  • 9
  • Show us how are you getting the value of that `*pbarquality` pointer – SingerOfTheFall Apr 03 '17 at 10:51
  • Use valgrind to verify that Qt has the bug, not your code. It will tell you exactly where the leak is coming from. – The Quantum Physicist Apr 03 '17 at 10:52
  • @SingerOfTheFall I never set or get it. I used the Qt Designer to create the GUI. – dcfyg Apr 03 '17 at 11:15
  • Interestingly when using setting a fixed value to setValue(), the problem doesn't occur either. @TheQuantumPhysicist I am working on Windows with VS2015. Is there any way to do this with VS? (Sorry I am never done this before) (Also sorry for double post) – dcfyg Apr 03 '17 at 11:18
  • @dcfyg On Windows there are profiling programs for the same purpose. I usually make my Windows programs cross-platform because of this issue, because Windows profiling programs are usually not free. If you can take that part of your code to Linux, then do it. Otherwise, google how to memory-analyze Visual Studio programs. Btw, if a fixed value doesn't cause a leak, then most likely there's nothing wrong with Qt. It's your code that has the problem. – The Quantum Physicist Apr 03 '17 at 11:20
  • Is any memory allocated in `getQuality()`? AFAIK `setValue` doesn't allocate any memory at all, it just sets the internal value, redraws the progress bar if needed, and emits a signal, so it can't leak. – SingerOfTheFall Apr 03 '17 at 11:20
  • @TheQuantumPhysicist I see, thanks. My first attempt suggests that OpenCV is using up the memory. I can't see any relation between the `setValue()`call and OpenCV. I will try looking into that further. @SingerOfTheFall No, `getQuality()` doesn't allocate any memory. Also it's called anyway regardless of the use of `setValue()`. I couldn't find any clue either that `setValue()`could have some memory issues that is why I find this behaviour strange. – dcfyg Apr 03 '17 at 11:46
  • if you can provide a compilable small example that shows the error we can always try to compile and test with valgrind on linux. – Tomaz Canabrava Apr 03 '17 at 12:48
  • If you have an answer to your own question, you know what to do: post it as an answer. It is fine and encouraged to answer your own questions. Once you do, please remove the "solution" part from the question: it never belongs there! – Kuba hasn't forgotten Monica Apr 05 '17 at 12:08

2 Answers2

1

Try replacing setValue by pbarQuality.update(); QCoreApplication::processEvents(); and see if that reproduces the problem. If it does, you're leveraging the nested event loop to keep the GUI responsive while your blocking code runs, and that's a bad thing. setValue calls processEvents as a naive way to work around broken user code. IMHO it's a dangerous favor. The only fix then is to unbreak your code and return control to the main event loop instead of blocking.

This answer shows how to avoid the effects of an image storm by leveraging the QImage's RAII behavior, and links to another answer that demonstrates free image scaling by leveraging OpenGL.

Community
  • 1
  • 1
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
0

My application runs another thread besides the GUI thread which periodically(up to 60 times per second) sends information(images) to the GUI thread. I am doing some minor image editing (resizing) within the GUI thread. Turns out this takes too long in order to keep up with the data posted by the other thread. Consequentially the event queue gets bigger and bigger and so does the used RAM too.

Lesson learned: Be aware of the processing speed of the thread if the data gets posted periodically. Data processing needs to be done before new data is available.

Thanks to @KubaOber for giving me the hint.

dcfyg
  • 75
  • 9
  • 1
    @chbchb55 I was hunting down the line of code which caused the supposed memory leak. When stepping through the application I took memory snapshots (in Visual Studio) after each step to figure out the point at the memory was increased. I commented out different lines of code until the supposed leak didn't occur anymore (this is when I suspected QProgressBar()::setValue() to be the problem. When I noticed that the accumulated RAM amount is about the size of the images and I read that emitted events are queued until they are processed it came to me what the issue was. – dcfyg Apr 07 '17 at 09:34