Petr Přikryl
Petr Přikryl

Reputation: 1812

String vector still reachable

I have this example code for string vector:

vector<string> strings;
strings.push_back(argv[0]);
cout << strings[0] << endl;
strings.clear();

exit(0);

But valgrind says:

==26012== HEAP SUMMARY:
==26012==     in use at exit: 8 bytes in 1 blocks
==26012==   total heap usage: 2 allocs, 1 frees, 41 bytes allocated
==26012== 
==26012== 8 bytes in 1 blocks are still reachable in loss record 1 of 1
==26012==    at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26012==    by 0x401DCF: __gnu_cxx::new_allocator<std::string>::allocate(unsigned long, void const*) (new_allocator.h:92)
==26012==    by 0x401BD8: std::_Vector_base<std::string, std::allocator<std::string> >::_M_allocate(unsigned long) (in /home/nich/IPK/2/client)
==26012==    by 0x401706: std::vector<std::string, std::allocator<std::string> >::_M_insert_aux(__gnu_cxx::__normal_iterator<std::string*, std::vector<std::string, std::allocator<std::string> > >, std::string const&) (vector.tcc:327)
==26012==    by 0x401421: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:834)
==26012==    by 0x401102: main (client.cc:130)
==26012== 
==26012== LEAK SUMMARY:
==26012==    definitely lost: 0 bytes in 0 blocks
==26012==    indirectly lost: 0 bytes in 0 blocks
==26012==      possibly lost: 0 bytes in 0 blocks
==26012==    still reachable: 8 bytes in 1 blocks
==26012==         suppressed: 0 bytes in 0 blocks

What I am doing wrong? String::clear method should call destructor on string shouldn't? Anyway I tried alternative way with pointers.

vector<string*> strings;
strings.push_back(new string(argv[0]));
cout << *(strings[0]) << endl;
delete strings[0];
strings.clear();

exit(0);

Valgrind:

==10177== HEAP SUMMARY:
==10177==     in use at exit: 8 bytes in 1 blocks
==10177==   total heap usage: 3 allocs, 2 frees, 49 bytes allocated
==10177== 
==10177== 8 bytes in 1 blocks are still reachable in loss record 1 of 1
==10177==    at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10177==    by 0x401CF9: __gnu_cxx::new_allocator<std::string*>::allocate(unsigned long, void const*) (new_allocator.h:92)
==10177==    by 0x401B5C: std::_Vector_base<std::string*, std::allocator<std::string*> >::_M_allocate(unsigned long) (in /home/nich/IPK/2/client)
==10177==    by 0x4016EA: std::vector<std::string*, std::allocator<std::string*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<std::string**, std::vector<std::string*, std::allocator<std::string*> > >, std::string* const&) (vector.tcc:327)
==10177==    by 0x4013F1: std::vector<std::string*, std::allocator<std::string*> >::push_back(std::string* const&) (stl_vector.h:834)
==10177==    by 0x4010C4: main (client.cc:130)
==10177== 
==10177== LEAK SUMMARY:
==10177==    definitely lost: 0 bytes in 0 blocks
==10177==    indirectly lost: 0 bytes in 0 blocks
==10177==      possibly lost: 0 bytes in 0 blocks
==10177==    still reachable: 8 bytes in 1 blocks
==10177==         suppressed: 0 bytes in 0 blocks

But still same problem. Can you please tell me how I should parse arguments from *argv[] to vector string without still reachable bytes?

Upvotes: 1

Views: 1188

Answers (2)

edwinbs
edwinbs

Reputation: 525

I think the 'leaked' 8 bytes refer to the STL container. The std::vector would not have been destructed by the time you exit. Try this:

{
  vector<string> strings;
  strings.push_back(argv[0]);
  cout << strings[0] << endl;
  strings.clear();
}
exit(0);

Upvotes: 2

mgibsonbr
mgibsonbr

Reputation: 22007

Calling strings.clear() is only emptying the vector, but the vector itself is still occupying memory. By statically creating it like this:

vector<string> strings;

it will still be on memory until the function goes out of scope (and since you called exit while in the function, it was still in scope when the program ended).

Upvotes: 7

Related Questions