0

Yesterday I ran into memory leakage problem when compiling my digital signal processing framework with GCC 4.8.2 under Windows. Implementing reference counts with C++

As is advised, I tried compiling my code with Visual Studio 2012 and troubles are gone. How should I diagnose this kind of problem? Thanks.

Community
  • 1
  • 1
babel92
  • 767
  • 1
  • 11
  • 21

3 Answers3

1

On Linux, you would use valgrind, so on Windows you could try one of the alternatives suggested in question Is there Valgrind Memcheck like tool for windows to debug use after free errors?.

Community
  • 1
  • 1
Oswald
  • 31,254
  • 3
  • 43
  • 68
  • Hi. I've tried some of them but since they need to be compiled together with the code with Visual Studio, and my code is working well under VS, they are not working... Maybe I need some leak checker working in a attaching manner. – babel92 Nov 17 '13 at 19:38
1

Well, you probably made some bad assumption about VS (e.g. that it is a nice compiler that will tell you when you made a mistake), and you wrote some non-standard compliant code.

The hopefully easiest way to diagnose this problem is by cranking up the warning level in GCC:

-std=c++11 -Wall -Wextra -pedantic

Make all these warnings go away, and with a bit of luck, your leak will be gone. If not, I would suggest compiling your code on Linux (if at all possible) and run it through valgrind, which will track down the issue that is bothering you.

rubenvb
  • 74,642
  • 33
  • 187
  • 332
1

The code in that other question isn't counting correctly from what I can tell. You initialize m_refcount to zero in the constructor and decrement it in the Delete function. Presumably there's a kind of AddRef or similar function too (which isn't shown) that increments the refcount.
The condition checked for in Delete is refcount > 1, which is off by one. Either it should be > 0 or >= 1.

However, I can't tell why this works with Visual Studio (are you sure? it probably doesn't work, because it's incorrect).

Also you do not seem to understand the purpose of a lock_guard. You don't allocate these on the heap, that makes no sense. You can just as well lock and unlock the mutex without a lock_guard then.
The purpose of lock_guard is that it's exception safe, so it must live on the stack.

Damon
  • 67,688
  • 20
  • 135
  • 185
  • Hi. I believe the correctness of the ref count mechanism is guaranteed by the data transfer layer, which is not shown in the code. But I fixed it according to your advice:) And I'm pretty sure it works with VS 2012 because data flow is observed in debug mode and the memory usage is at a steady state. As for the lock_guard, I used to believe the only thing I need to do is to make its lifetime right and it has nothing to do with on stack or on heap(so long as I new it when get into the function and call delete when exit). So this is wrong? – babel92 Nov 17 '13 at 19:32
  • @babel92, The issue with dynamically allocating and freeing the lockguard is that you have taken full responsibility for it's lifetime (all those pesky new and delete calls...). And, put simply, your lifetime management is not as good as the compiler's for stack-based objects. For example, if `m_refcnt--` throws an exception (not impossible, as we know nothing about its type) then the function exits with the lock still held. Yes you could fix this by using a try/catch block, but what's the point? Objects should be stack-based whenever possible. – Roddy Nov 17 '13 at 20:09
  • 1
    @babel92: This is one of the "common applications for RAII". You have guaranteed exception-safe unlocking because the `lock_guard` will be destroyed _either_ when the function returns (or when it goes out of scope otherwise) _or_ when the stack is unwound. That is not the case if you allocate it dynamically, which makes the entire purpose of using a `lock_guard` obsolete. – Damon Nov 17 '13 at 20:22