Search code examples
c++memory-leaksvalgrind

Why does memory leak in one case and not in another


I am creating a c++ object with two slightly different ways, in the following code when CASE is 0 there is a memory leak, but no memory leak in the else case.

#include <string>
#define CASE 1

class A {
private:
  std::string *s;
public:
  A(std::string *p_s) { s = p_s; }
};

int main() {
#if CASE==0
  auto a = A(new std::string("Hello"));
#else
  auto s = std::string("Hello");
  auto a = A(&s);
#endif
}

when I set CASE 0 the valgrind says that there is a memory leak

valgrind ./a.out 
==24351== Memcheck, a memory error detector
==24351== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==24351== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==24351== Command: ./a.out
==24351== 
==24351== 
==24351== HEAP SUMMARY:
==24351==     in use at exit: 32 bytes in 1 blocks
==24351==   total heap usage: 2 allocs, 1 frees, 72,736 bytes allocated
==24351== 
==24351== LEAK SUMMARY:
==24351==    definitely lost: 32 bytes in 1 blocks
==24351==    indirectly lost: 0 bytes in 0 blocks
==24351==      possibly lost: 0 bytes in 0 blocks
==24351==    still reachable: 0 bytes in 0 blocks
==24351==         suppressed: 0 bytes in 0 blocks
==24351== Rerun with --leak-check=full to see details of leaked memory
==24351== 
==24351== For counts of detected and suppressed errors, rerun with: -v
==24351== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

in the else case (i.e. define CASE 1) it works as expected and valgrind doesn't report any memory leak.

I am not able to understand in either case I am passing a pointer and I am not explicitly freeing the memory then why do they behave differently?


Solution

  • CASE==0

    auto a = A(new std::string("Hello"));
    

    This means you are new-ing an object in heap -> you have to explicitly delete it - that you didn't in the snippet -> memory leaks.

    else

    auto s = std::string("Hello");
    auto a = A(&s);
    
    • auto s = std::string("Hello");: This means you are creating an object in stack and,
    • auto a = A(&s);: take its address (in stack, of course).
    • The created object will be auto-deleted once the variable goes out of scope

    -> no memory leak.