std::string causing memory leaks - c++

I am running into a situation where my application is having memory leaks. After running valgrind, it looks as if I am getting a memory leak related to a std::string:
==20274== 34 bytes in 1 blocks are definitely lost in loss record 34 of 140
==20274== at 0x4C29DB5: operator new(unsigned long) (vg_replace_malloc.c:332)
==20274== by 0x7F843C8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.13)
==20274== by 0x7F84DE4: ??? (in /usr/lib64/libstdc++.so.6.0.13)
==20274== by 0x7F84F32: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.13)
==20274== by 0xA50CC71: __static_initialization_and_destruction_0(int, int) (filename.cpp:22)
==20274== by 0xA50D03F: _GLOBAL__sub_I_filename.cpp (filename.cpp:112)
==20274== by 0x400E9CE: _dl_init (in /lib64/ld-2.12.so)
==20274== by 0x4000B69: ??? (in /lib64/ld-2.12.so)
The code in question is:
in filename.h:
extern std::string aString;
in filename.cpp:
std::string aString = "a string";
Also worth note, this is in a separate namespace i.e.
namespace aNamespace {
//...
std::string aString; // in extern in .h
//...
}
Every place in code, it is (of course) referenced as:
aNamespace::aString;
And, from what I can tell, it is never reset, and is used either as a constant reference, or to initialize another string.
Can there ever be a situation where std::string would give memory leaks?
edit:
A related portion of the valgrind output:
==20274== by 0x400EFBB: _dl_fini (in /lib64/ld-2.12.so)
==20274== by 0x88DAA01: exit (in /lib64/libc-2.12.so)
==20274== by 0x88C3D26: (below main) (in /lib64/libc-2.12.so)
Is this making an exit call? Is it the standard exit(0)?

Valgrind produces this kind of messages if on program termination there's still some heap-allocated memory, but no variable holds a pointer to.
std::string allocates memory in it's constructor to provide storage for chars. Destructor should free memory back.
My guess is that application is terminated using exit(0) or so. In this case stack does not unwind, and no destructors are called.

Related

C++, Valgrind reporting "possibly lost" after char* to std::string "conversion"

I have a class with a constructor like,
Foo::Foo(string p) {
path = p;
}
And I use it like this,
Foo foo = Foo("/tmp/foo");
Sorry for my C++ naivety. I understand that this is creating a std::string object implcitly (what's the right terminology for what's going on here?).
This causes Valgrind to complain as such,
==28188== 66 bytes in 1 blocks are possibly lost in loss record 3 of 5
==28188== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28188== by 0x4EFBF28: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EFD9B4: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EFDDDB: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EC2B05: std::logic_error::logic_error(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EC5AA8: std::__throw_logic_error(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EFDA38: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EFDDDB: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4022F3: main (main.cpp:13)
==28188==
==28188== 144 bytes in 1 blocks are possibly lost in loss record 4 of 5
==28188== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28188== by 0x4E9FF9F: __cxa_allocate_exception (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EC5A92: std::__throw_logic_error(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EFDA38: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4EFDDDB: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.24)
==28188== by 0x4022F3: main (main.cpp:13)
It looks like ultimately the "conversion" (sorry again) new'ing a std::string.
If I change my code to this,
string d = string("/tmp");
Foo Foo = Foo(d);
Valgrind does not report the leak.
This is really a leak, right? Seems like it.
What's the proper idiom to do what I'm doing here? I want the call semantics to be able to pass a char* but internally I want the class member to be a std::string.
The Valgrind error that you're getting seems to suggest that your program terminated abnormally due to an exception. You can see this through the call stack: it looks like an internal std::__throw_exception function is getting called and that there's an object of type std::logic_error getting constructed. From context, it seems like what's happening here is that you passed an invalid argument into the std::string constructor, which then caused the std::logic_error to get thrown, causing a different std::string to get constructed and then thrown. Since the program terminated due to an exception, the destructors for the std::strings constructed this way never got called, hence the leak.
I'd run this program in gdb rather than valgrind to see if you can debug the source of the error. From what you've posted above I don't think we have enough context to provide any specific insights.
Problem here is when you passed string literal which is actually of type const char * (c string) to const string , compiler creates temporary object by invoking overaloded ctor string(const char * ). This temporary object is then passed by value to Foo().
Temporary object of type string has internal allocation created something on heap and it should be freed when temporary object goes out of scope.
This is not definite memory leak but valgrind thinks (due to temp object doesnot have definite starting pointer pointing to it) in that way.
That's the reason it is reported as possbily lost (and not definitely lost).
The idiom I like to use is Foo::Foo(const std::string &str)
Passes strings by reference, but also allows for string literals.
The one thing to look out for is a NULL char pointer. That is quite possibly what you are seeing.

Valgrind supplying question marks

I'm trying to track down some mysterious crashes that seem to be memory-related thus far. So, I've started using Valgrind to get it done. I've never used it before, but the first run gave me some good information. Today I had a chance to run it again (the circumstance in which we see a crash isn't reproducible) and the output was decidedly less useful.
==11831==
==11831== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==11831== Bad permissions for mapped region at address 0x75EAB8
==11831== at 0x75EAB8: ??? (in /usr/local/bin/test-app.V1.88)
==11831== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==11831== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==11831== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==11831== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==11831== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==11831== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==11831== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==11831==
==11831== HEAP SUMMARY:
==11831== in use at exit: 3,611,867 bytes in 12,934 blocks
==11831== total heap usage: 15,871 allocs, 2,937 frees, 26,483,142 bytes allocated
==11831==
==11831== LEAK SUMMARY:
==11831== definitely lost: 0 bytes in 0 blocks
==11831== indirectly lost: 0 bytes in 0 blocks
==11831== possibly lost: 206,203 bytes in 7,146 blocks
==11831== still reachable: 3,405,664 bytes in 5,788 blocks
==11831== suppressed: 0 bytes in 0 blocks
==11831== Rerun with --leak-check=full to see details of leaked memory
==11831==
==11831== For counts of detected and suppressed errors, rerun with: -v
==11831== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
So, I ran it again with --leak-check=full and it did give me more:
==13764==
==13764== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==13764== Bad permissions for mapped region at address 0x75EAB8
==13764== at 0x75EAB8: ??? (in /usr/local/bin/test-app.V1.88)
==13764== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==13764== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==13764== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==13764== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==13764== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==13764== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==13764== by 0x75EAB7: ??? (in /usr/local/bin/test-app.V1.88)
==13764==
==13764== HEAP SUMMARY:
==13764== in use at exit: 3,611,867 bytes in 12,934 blocks
==13764== total heap usage: 15,871 allocs, 2,937 frees, 26,483,154 bytes allocated
==13764==
==13764== 26 bytes in 1 blocks are possibly lost in loss record 5 of 343
==13764== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13764== by 0x4ED0A88: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED0C79: std::string::_M_mutate(unsigned long, unsigned long, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED0E1B: std::string::_M_replace_safe(unsigned long, unsigned long, char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4D48B3: abc::load_config_file(std::string) (abc_read_config_file.cpp:46)
==13764== by 0x4C0A3A: AppStartup(int, char**, char const*) (AppBase.cpp:58)
==13764== by 0x49BFC1: main (App.cpp:54)
==13764==
==13764== 28 bytes in 1 blocks are possibly lost in loss record 6 of 343
==13764== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13764== by 0x4ED0A88: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED2494: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED25E2: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4FCB74: __static_initialization_and_destruction_0(int, int) (xyzLib.cc:46)
==13764== by 0x4FCD12: _GLOBAL__sub_I_xyzLib.cc (xyzLib.cc:2179)
==13764== by 0x52280C: __libc_csu_init (in /usr/local/bin/test-app.V1.88)
==13764== by 0x58826FF: (below main) (libc-start.c:185)
==13764==
==13764== 28 bytes in 1 blocks are possibly lost in loss record 7 of 343
==13764== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13764== by 0x4ED0A88: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED22B4: char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED2414: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&, unsigned long, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED2441: std::string::substr(unsigned long, unsigned long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x500E27: XyzParameter::getField(std::string&, char const*, std::string const&, unsigned long&, bool) (xyzMessageCodec.hh:1186)
==13764== by 0x500FBB: XyzParameter::getFields(std::vector<std::string, std::allocator<std::string> >&, int, std::string const&, bool) (xyzMessageCodec.hh:1219)
==13764== by 0x5021F3: XyzParameter::getPositionsList(std::string const&) (xyzMessageCodec.hh:1414)
==13764== by 0x4FAF0B: Xyz::XyzLib::MessageHandler::handleOpenPositionsResponse(void*) (xyzLib.cc:1854)
==13764== by 0x4F8F08: Xyz::XyzLib::MessageHandler::handleXyzMsg(void*) (xyzLib.cc:1444)
==13764== by 0x4F7CCC: Xyz::XyzLib::MessageHandler::onMsg(Xyz::Xyz::XyzMessage*) (xyzLib.cc:1211)
==13764== by 0x51101D: Xyz::Xyz::XyzSession::processNextMsg() (xyzSession.cc:270)
==13764==
==13764== 29 bytes in 1 blocks are possibly lost in loss record 8 of 343
==13764== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13764== by 0x4ED0A88: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED2494: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED25E2: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4A62CE: __static_initialization_and_destruction_0(int, int) (Distributor.h:190)
==13764== by 0x4A659F: _GLOBAL__sub_I_abc.cpp (abc.cpp:522)
==13764== by 0x52280C: __libc_csu_init (in /usr/local/bin/test-app.V1.88)
==13764== by 0x58826FF: (below main) (libc-start.c:185)
==13764==
==13764== 29 bytes in 1 blocks are possibly lost in loss record 9 of 343
==13764== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13764== by 0x4ED0A88: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED2494: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4ED25E2: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16)
==13764== by 0x4A6311: __static_initialization_and_destruction_0(int, int) (Distributor.h:190)
==13764== by 0x4A659F: _GLOBAL__sub_I_abc.cpp (abc.cpp:522)
==13764== by 0x52280C: __libc_csu_init (in /usr/local/bin/test-app.V1.88)
==13764== by 0x58826FF: (below main) (libc-start.c:185)
And on it goes for another 14,000 lines and a few PID's.
My question is: what exactly is this reporting? The last time I ran valgrind on an app crashing like this, I was pointed squarely at the destructor of a class, specifically of a std::string data member of that class. This time, however, valgrind only has question marks for me and a whole lot more dealing with the new operator from std::string. I'm genuinely unaware how one might proceed with this information to arrive at some sort of conclusion and fix a bug or four.
EDIT Here are the specific lines valgrind is suspicious of:
app_params.tracked_symbol="a";
const std::string XyzLib::LANGUAGE_ID = "C++";
The next two are a return statement and the closing brace of a class. It continues like that for quite a few instances of valgrind's concern (closing braces of the several classes).

Memory Leak using C++ Exceptions

I'm struggling to write a little file handle class in C++11.
I know there already is a lot in the STL to actually handle files, but for learning purposes I wanted to do this by myself.
Unfortunately I don't seem understand, what effect exceptions have on the memory leakage behavior of a C++ program because Valgrind tells me, there are 2 memory leaks in following code:
file.h
#ifndef FILE_H
#define FILE_H
#include <iostream>
#include <memory>
#include <string>
#include <stdio.h>
class FileDeleter {
public:
void operator()(FILE *p);
};
class File {
public:
File(const std::string path);
private:
const std::string _path;
std::unique_ptr<FILE, FileDeleter> _fp;
};
#endif // FILE_H
file.cpp
#include <cstring>
#include <iostream>
#include <stdexcept>
#include <utility>
#include <stdio.h>
#include "file.h"
void FileDeleter::operator()(FILE *p)
{
if (!p)
return;
if (fclose(p) == EOF)
std::cerr << "FileDeleter: Couldn't close file" << std::endl;
}
File::File(const std::string path)
: _path(std::move(path)),
_fp(fopen(_path.c_str(), "a+"))
{
if (!_fp)
throw std::runtime_error("Couldn't open file");
}
main.cpp
#include <cstdlib>
#include "file.h"
int main()
{
File my_file("/root/.bashrc");
return EXIT_SUCCESS;
}
I did choose to open /root/.bashrc on purpose to actually make the File ctor throw the exception. If I don't throw there, Valgrind is perfectly happy.
What am I missing here in using exceptions?
How do you implement a simple file handle "correctly" (exception safe)?
Thanks in advance!
Note: the read/write operations are still missing, since I'm already struggling with the basics.
Edit #1:
This is the actual Valgrind output, using --leak-check=full:
==7998== HEAP SUMMARY:
==7998== in use at exit: 233 bytes in 3 blocks
==7998== total heap usage: 5 allocs, 2 frees, 817 bytes allocated
==7998==
==7998== 38 bytes in 1 blocks are possibly lost in loss record 1 of 3
==7998== at 0x4C27CC2: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7998== by 0x4EEC4F8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.18)
==7998== by 0x4EEDC30: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/libstdc++.so.6.0.18)
==7998== by 0x4EEE047: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.18)
==7998== by 0x40137D: main (in ../a.out)
==7998==
==7998== 43 bytes in 1 blocks are possibly lost in loss record 2 of 3
==7998== at 0x4C27CC2: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7998== by 0x4EEC4F8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.18)
==7998== by 0x4EEDC30: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/libstdc++.so.6.0.18)
==7998== by 0x4EEE047: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.18)
==7998== by 0x400EBF: File::File(std::string) (in /home/frank/3Other/Code/Laboratory/c++/c++namedpipe/a.out)
==7998== by 0x401390: main (in ../a.out)
==7998==
==7998== 152 bytes in 1 blocks are possibly lost in loss record 3 of 3
==7998== at 0x4C27730: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7998== by 0x4E8F8F2: __cxa_allocate_exception (in /usr/lib/libstdc++.so.6.0.18)
==7998== by 0x400E9B: File::File(std::string) (in /home/frank/3Other/Code/Laboratory/c++/c++namedpipe/a.out)
==7998== by 0x401390: main (in ../a.out)
==7998==
==7998== LEAK SUMMARY:
==7998== definitely lost: 0 bytes in 0 blocks
==7998== indirectly lost: 0 bytes in 0 blocks
==7998== possibly lost: 233 bytes in 3 blocks
==7998== still reachable: 0 bytes in 0 blocks
==7998== suppressed: 0 bytes in 0 blocks
Edit #2:
Fixed exception thrown in Destructor.
Edit #3:
Removed FileException class, using std::runtime_error instead.
Edit #4:
Added NULL check in deleter.
I see the following problems:
fclose(NULL) is not allowed ...
but fortunately std::unique_ptr doesn't call the deleter if get() == nullptr, so this should be ok here
FileDeleter:operator() is called from a destructor, which means it should never throw. In your specific case, any error returned from fclose will cause std::terminate to be called
your exception should store the string by value, not reference. That reference is to a temporary which will have been destroyed by the time you call what().
As Vlad & Praetorian pointed out, you can remove the buggy code instead of fixing it, and just let std::runtime_error handle that for you. TBH, unless you're planning to add some file-specific data to the exception, or you plan to catch file exceptions separately, you don't need this class at all.
Edit: with the valgrind output provided, it looks like stack unwinding never completed. Since my initial thought about FileDeleter::operator() being called and throwing looks wrong, a reasonable test would be: what happens if you stick a try/catch inside the body of main?
General notes:
never throw an exception inside a destructor
never call something else that might throw, from a destructor
because if your destructor is invoked during exception handling/stack unwinding, the program will terminate instantly.

Valgrind error with std::cin

Here is my code:
std::string getword()
{
std::string temp;
std::cin >> temp;
return temp;
}
Valgrind throws an error on the line std::cin >> temp.
Here is the valgrind output for those who asked:
HEAP SUMMARY:
==18490== in use at exit: 33 bytes in 1 blocks
==18490== total heap usage: 397 allocs, 396 frees, 12,986 bytes allocated
==18490==
==18490== 33 bytes in 1 blocks are possibly lost in loss record 1 of 1
==18490== at 0x4C2AF8E: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18490== by 0x4EEE3B8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==18490== by 0x4EEF127: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==18490== by 0x4EEF20F: std::string::reserve(unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==18490== by 0x4EA7D14: std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==18490== by 0x401681: getword() (netsim.cc:29)
==18490== by 0x401F6E: main (netsim.cc:96)
==18490==
==18490== LEAK SUMMARY:
==18490== definitely lost: 0 bytes in 0 blocks
==18490== indirectly lost: 0 bytes in 0 blocks
==18490== possibly lost: 33 bytes in 1 blocks
==18490== still reachable: 0 bytes in 0 blocks
==18490== suppressed: 0 bytes in 0 blocks
==18490==
==18490== For counts of detected and suppressed errors, rerun with: -v
==18490== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
netsim.cc:96 is the second call to getword() in the program. That code reads
std::string network = getword();
netsim.cc:29 is the code for getword() itself. Line 29 is the line
std::cin >> temp
I still don't understand why this happened but I managed to resolve the issue.
I had the code
std::string s = getword();
immediatly above
std::string network = getword();
I made both s and network global variables and somehow the issue was resolved.
If anyone can explain why that is though I would be grateful.
I'm not a valgrind Expert, but I'm tentative to say that this is a false positive. In fact, it might even be a false positive generated by valgrind itself. Looking at the Leak Summary and seeing the core origin of the leak, I get suspicious:
// The one right below this, that's at the top of that valgrind error
==18490== at 0x4C2AF8E: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18490== by 0x4EEE3B8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
Now why would valgrind be reporting a memory leak from its own shared library ? Something doesn't seem right here. Either valgrind itself isn't very clean in how its allocating that memory (and valgrind has its own leak! Oh noes!) or it's throwing a really strange false positive. Unless the newest branches of GCC have produced a memory leak for std::string and the istream& operator<< recently, I can't imagine this actually leaking. std::cin and std::cout have been being used for ages, and it makes no sense that valgrind would toss an error over it, especially when your client code isn't making a single new/delete call.
So, in short, there's a few things that could be happening here:
valgrind is leaking. (Maybe? It's originating from a valgrind function)
GCC is leaking? (Hesitant to say this)
valgrind is drunk! :[
In either case, ignore it and move on. I doubt this is going to shatter your netsim in any crucial way.
I hope it clears up soon, and I'm sorry my answer can only say this much, but these are the best shots I can give.

std::string memory leak

I've got this class AppController and the function connectPlayer:
/* AppController.h */
class AppController
{
// Some other declarations ...
private:
static const string TAG;
};
/* AppController.cpp */
#include "AppController.h"
const string AppController::TAG = "AppController";
AppController::AppController() {
/* some code here...*/
}
void AppController::connectPlayer() {
std::string port;
std::string host;
port = CM->getMenu()->getData("PORT");
host = CM->getMenu()->getData("HOST");
this->setState("Connecting...");
Logger::info(TAG, "Port: " + port);
Logger::info(TAG, "Host: " + host);
}
And when I execute the program, I get this from valgrind:
==7848== 25 bytes in 1 blocks are definitely lost in loss record 160 of 671
==7848== at 0x402842F: operator new(unsigned int) (vg_replace_malloc.c:255)
==7848== by 0x4210A83: std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==7848== by 0x4212CF7: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==7848== by 0x4212E65: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16)
==7848== by 0x8080501: AppController::connectPlayer() (in /home/maine/Escritorio/taller7542/UltimaVersion/src/main)
Any ideas? Thank you in advance!
You have std::string objects in global scope: AppController::TAG.
When application finished in not very normal way you've got these kind of valgrind errors for global objects. Probably nothing to worry.
If you (cannot/don't want to) change your program - read this doc: http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress to get rid of this very error.
Sometimes, valgrind gives false positives. This means that even if valgrind says you lose memory, actually you don't.
The only thing to worry about is when you call the exit() function, as explained in this question.
If you do not want to see these warnings any more, you can create a suppressions file giving valgrind some information on which errors to ignore.
I had seen this issue once when I had a string in a class in global scope. Valgrind kept complaining that I was leaking memory. I just "deleted" the object at exit and the error was gone.