valgrind detects errors when c++ exception is not caught - c++

I notice that the valgrind reports possible memory leak for the following minimal example:
#include <stdexcept>
int main() {
try {
throw std::logic_error("test");
}
catch (std::exception& e) {
std::string msg("test2 ");
msg.append(e.what());
throw std::logic_error(msg);
}
return 0;
}
After compiling it with g++ test.cpp -g, the valgrind detects some errors with valgrind --tool=memcheck --leak-check=full ./a.out. Is this normal?
I concern this issue because the valgrind reports some errors of my R extensions which is similar to this example.
The valgrind version is: 3.10.0.SVN. The gcc version is 4.8.2 (Ubuntu 4.8.2-19ubuntu1). The reported message is shown below:
==8640== Memcheck, a memory error detector
==8640== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==8640== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==8640== Command: ./a.out
==8640==
terminate called after throwing an instance of 'std::logic_error'
what(): test2 test
==8640==
==8640== HEAP SUMMARY:
==8640== in use at exit: 354 bytes in 4 blocks
==8640== total heap usage: 6 allocs, 2 frees, 417 bytes allocated
==8640==
==8640== 29 bytes in 1 blocks are possibly lost in loss record 1 of 4
==8640== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8640== by 0x4EF13B8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x4EF2AE0: 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.19)
==8640== by 0x4EF2EF7: 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.19)
==8640== by 0x400BA7: main (test.cpp:4)
==8640==
==8640== 37 bytes in 1 blocks are possibly lost in loss record 2 of 4
==8640== at 0x4C2B0E0: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8640== by 0x4EF13B8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x4EF1F7A: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x4EF2013: std::string::reserve(unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x4EF225E: std::string::append(char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x400CC6: main (test.cpp:8)
==8640==
==8640== 144 bytes in 1 blocks are possibly lost in loss record 3 of 4
==8640== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8640== by 0x4E944E2: __cxa_allocate_exception (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x400B83: main (test.cpp:4)
==8640==
==8640== 144 bytes in 1 blocks are possibly lost in loss record 4 of 4
==8640== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8640== by 0x4E944E2: __cxa_allocate_exception (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==8640== by 0x400CD0: main (in /home/wush/Test/a.out)
==8640==
==8640== LEAK SUMMARY:
==8640== definitely lost: 0 bytes in 0 blocks
==8640== indirectly lost: 0 bytes in 0 blocks
==8640== possibly lost: 354 bytes in 4 blocks
==8640== still reachable: 0 bytes in 0 blocks
==8640== suppressed: 0 bytes in 0 blocks
==8640==
==8640== For counts of detected and suppressed errors, rerun with: -v
==8640== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 1 from 1)
Aborted (core dumped)

Related

valgrind shows memory leak in vector constructor

I am writing a compiler using bison and C++, and I just checked memory leak with Valgrind. While it shows there's memory leak caused by vector constructor shown below:
==6562== HEAP SUMMARY:
==6562== in use at exit: 90,298 bytes in 27 blocks
==6562== total heap usage: 125 allocs, 98 frees, 100,782 bytes allocated
==6562==
==6562== 80 (32 direct, 48 indirect) bytes in 1 blocks are definitely lost in loss record 19 of 22
==6562== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6562== by 0x40DB9B: __gnu_cxx::new_allocator<std::shared_ptr<Node> >::allocate(unsigned long, void const*) (new_allocator.h:104)
==6562== by 0x40D3B9: std::allocator_traits<std::allocator<std::shared_ptr<Node> > >::allocate(std::allocator<std::shared_ptr<Node> >&, unsigned long) (alloc_traits.h:491)
==6562== by 0x40C465: std::_Vector_base<std::shared_ptr<Node>, std::allocator<std::shared_ptr<Node> > >::_M_allocate(unsigned long) (stl_vector.h:170)
==6562== by 0x41C170: std::_Vector_base<std::shared_ptr<Node>, std::allocator<std::shared_ptr<Node> > >::_M_create_storage(unsigned long) (stl_vector.h:185)
==6562== by 0x41ADB6: std::_Vector_base<std::shared_ptr<Node>, std::allocator<std::shared_ptr<Node> > >::_Vector_base(unsigned long, std::allocator<std::shared_ptr<Node> > const&) (stl_vector.h:136)
==6562== by 0x41A13F: std::vector<std::shared_ptr<Node>, std::allocator<std::shared_ptr<Node> > >::vector(std::vector<std::shared_ptr<Node>, std::allocator<std::shared_ptr<Node> > > const&) (stl_vector.h:320)
==6562== by 0x417ECF: OprNode::OprNode(int, std::vector<std::shared_ptr<Node>, std::allocator<std::shared_ptr<Node> > > const&) (Node.cpp:52)
==6562== by 0x406C7B: opr(int, std::vector<Node*, std::allocator<Node*> > const&) (parser.y:175)
==6562== by 0x40555B: yyparse() (parser.y:125)
==6562== by 0x40748B: main (parser.y:253)
==6562==
==6562== LEAK SUMMARY:
==6562== definitely lost: 32 bytes in 1 blocks
==6562== indirectly lost: 48 bytes in 2 blocks
==6562== possibly lost: 0 bytes in 0 blocks
==6562== still reachable: 90,218 bytes in 24 blocks
==6562== suppressed: 0 bytes in 0 blocks
==6562== Reachable blocks (those to which a pointer was found) are not shown.
==6562== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==6562==
==6562== For counts of detected and suppressed errors, rerun with: -v
==6562== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Relevant code:
class Node {
public:
Node()=default;
virtual void ex(int, int, int) const = 0;
virtual void check(vector<int>&, int) const = 0;
};
class OprNode:public Node {
public:
OprNode(int, const vector<shared_ptr<Node>>&);
void ex(int, int, int) const;
void check(vector<int>&, int) const;
private:
int oper;
vector<shared_ptr<Node>> op;
};
OprNode::OprNode(int oper, const vector<shared_ptr<Node> >& op):oper(oper), op(op) {;}
Node * opr(int oper, const vector<Node *>& op) {
auto v = vector<shared_ptr<Node> >();
for (const auto i: op) {
v.push_back(shared_ptr<Node>(i));
}
return new OprNode(oper, v);
}
Due to the limitation of bison, I must use raw pointer as the return type and content of vector passed into opr.
Thanks a lot!

Extremely simple C++ program memory leak

I have been scratching my head over this memory leak in a extremely simple C++ program. I properly delete the only pointer allocation but a ridiculous amount of memory leak still occurs. None of my classes even have variables.
All the methods only prints a sinple hard coded string
main
#include <iostream>
#include "queen.h"
#include "piece.h"
using namespace std;
void printPiece(piece *p) {
cout<<"In printPiece, printType() of the same memory address is:"<<endl;
p->printType();
}
int main() {
queen *q = new queen();
cout<<"In main, printType() of queen *q is:"<<endl;
q->printType();
printPiece(q);
delete q;
return 0;
}
piece class
#ifndef _PIECE_H
#define _PIECE_H
class piece {
public:
void printType();
};
#endif
Queen
#ifndef _QUEEN_H
#define _QUEEN_H
#include "piece.h"
class queen : public piece{
public:
void printType();
};
#endif
Valgrind on MacOS
HEAP SUMMARY:
==8775== in use at exit: 26,145 bytes in 190 blocks
==8775== total heap usage: 257 allocs, 67 frees, 31,922 bytes allocated
==8775==
==8775== 2,064 bytes in 1 blocks are possibly lost in loss record 58 of 62
==8775== at 0x10000B942: malloc_zone_malloc (in /usr/local/Cellar/valgrind/3.12.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==8775== by 0x1005E6EFD: _objc_copyClassNamesForImage (in /usr/lib/libobjc.A.dylib)
==8775== by 0x1005DA182: protocols() (in /usr/lib/libobjc.A.dylib)
==8775== by 0x1005DA093: readClass(objc_class*, bool, bool) (in /usr/lib/libobjc.A.dylib)
==8775== by 0x1005D7C13: gc_init (in /usr/lib/libobjc.A.dylib)
==8775== by 0x1005DF24E: objc_initializeClassPair_internal(objc_class*, char const*, objc_class*, objc_class*) (in /usr/lib/libobjc.A.dylib)
==8775== by 0x1005EC132: layout_string_create (in /usr/lib/libobjc.A.dylib)
==8775== by 0x1005DA83C: realizeClass(objc_class*) (in /usr/lib/libobjc.A.dylib)
==8775== by 0x1005DA300: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==8775== by 0x1005DA2E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==8775== by 0x1005DA2E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==8775== by 0x1005DA2E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
==8775==
==8775== LEAK SUMMARY:
==8775== definitely lost: 0 bytes in 0 blocks
==8775== indirectly lost: 0 bytes in 0 blocks
==8775== possibly lost: 2,064 bytes in 1 blocks
==8775== still reachable: 4,096 bytes in 1 blocks
==8775== suppressed: 19,985 bytes in 188 blocks
==8775== Reachable blocks (those to which a pointer was found) are not shown.
==8775== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==8775==
==8775== For counts of detected and suppressed errors, rerun with: -v
==8775== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 14 from 14)
Valgrind on Ubuntu
==32313== Memcheck, a memory error detector
==32313== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==32313== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==32313== Command: ./main
==32313==
In main, printType() of queen *q is:
Queen
In printPiece, printType() of the same memory address is:
Unknown Piece Type
==32313==
==32313== HEAP SUMMARY:
==32313== in use at exit: 72,704 bytes in 1 blocks
==32313== total heap usage: 3 allocs, 2 frees, 73,729 bytes allocated
==32313==
==32313== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==32313== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32313== by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32313== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==32313== by 0x40105FA: call_init (dl-init.c:30)
==32313== by 0x40105FA: _dl_init (dl-init.c:120)
==32313== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==32313==
==32313== LEAK SUMMARY:
==32313== definitely lost: 0 bytes in 0 blocks
==32313== indirectly lost: 0 bytes in 0 blocks
==32313== possibly lost: 0 bytes in 0 blocks
==32313== still reachable: 72,704 bytes in 1 blocks
==32313== suppressed: 0 bytes in 0 blocks
==32313==
==32313== For counts of detected and suppressed errors, rerun with: -v
==32313== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
The memory leak is completely unrelated to your program compilation units. Somewhere, somehow parts of the Swift and Objective-C language runtimes are linked into your program. Somewhere in there a garbage collector enters the picture. And Valgrind simply is telling you, that your program did exit with still a few garbage collected allocations being (before the garbage collector could free them).
In general when using a garbage collector you'll always see memory leak errors with Valgrind.

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).

getline() valgrind memory leak

I am getting a memory leak with getline, and I am not sure why or how to stop it.
Here is the report from valgrind:
==26681==
==26681== HEAP SUMMARY:
==26681== in use at exit: 1,756 bytes in 73 blocks
==26681== total heap usage: 223 allocs, 150 frees, 15,523 bytes allocated
==26681==
==26681== 28 bytes in 1 blocks are possibly lost in loss record 1 of 4
==26681== at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298)
==26681== by 0x4CCC4B8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (new_allocator.h:94)
==26681== by 0x4CCD227: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (basic_string.tcc:631)
==26681== by 0x4CCD30F: std::string::reserve(unsigned long) (basic_string.tcc:512)
==26681== by 0x4CCD5D4: std::string::append(char const*, unsigned long) (basic_string.tcc:310)
==26681== by 0x4C86384: std::basic_istream<char, std::char_traits<char> >& std::getline<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> >&, char) (istream.cc:397)
==26681== by 0x4026ED: main (test.cpp:210)
==26681==
==26681== LEAK SUMMARY:
==26681== definitely lost: 0 bytes in 0 blocks
==26681== indirectly lost: 0 bytes in 0 blocks
==26681== possibly lost: 28 bytes in 1 blocks
==26681== still reachable: 1,728 bytes in 72 blocks
==26681== suppressed: 0 bytes in 0 blocks
==26681== Reachable blocks (those to which a pointer was found) are not shown.
==26681== To see them, rerun with: --leak-check=full --show-reachable=yes
==26681==
==26681== For counts of detected and suppressed errors, rerun with: -v
==26681== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)
Here is line 210 of test.cpp
bool pending = getline(inputfile, line);
Some more lines:
string line;
bool pending = getline(inputfile, line);
int round = readOption(inputfile);
int num = readOption(inputfile);
I think it has something to do with when getline fails, and because line is a string it somehow never deallocates that memory. How do I prevent this?
readOption also uses getline but I think it has no memory leaks because string line is defined locally and then goes out of scope, effectively cleaning the memory?
Edit 1:
I have "solved" the issue by making a dummy function :
bool getnewline(ifstream &inputfile) {
string line;
return getline(inputfile, line);
}
However it seems stupid to do this, I am not sure why valgrind is complaining if there is no leak. I am still after a better/clean solution to this issue.
When you exit a C++ program by calling the exit() function, the object destructors are not run. This can result in Valgrind reporting memory leaks.
I know this is almost a year old but I came upon this answer looking specifically for a getline() memory leak issue and want to give minimum instructions on how I was able to reproduce this specific issue, as I think it just comes from defining a std::string variable and not exiting cleanly from the program.
Given the following:
leaky.cpp:
#include <iostream>
int main(int argc, char ** argv) {
std::string x = "x";
exit(1);
return 0;
}
Compile string:
g++ -g -Wall -Wpedantic --std=gnu++11 leaky.cpp -o leaky
Valgrind invocation:
valgrind --tool=memcheck --leak-check=full ./leaky
Doing this will reveal that there is indeed a leak:
==4434== Memcheck, a memory error detector
==4434== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4434== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==4434== Command: ./leaky
==4434==
==4434==
==4434== HEAP SUMMARY:
==4434== in use at exit: 16 bytes in 1 blocks
==4434== total heap usage: 1 allocs, 0 frees, 16 bytes allocated
==4434==
==4434== 16 bytes in 1 blocks are possibly lost in loss record 1 of 1
==4434== at 0x402A6DC: operator new(unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4434== by 0x40F8213: std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.19)
==4434== by 0x40FA125: 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.19)
==4434== by 0x40FA7AF: 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.19)
==4434== by 0x804875E: main (leaky.cpp:3)
==4434==
==4434== LEAK SUMMARY:
==4434== definitely lost: 0 bytes in 0 blocks
==4434== indirectly lost: 0 bytes in 0 blocks
==4434== possibly lost: 16 bytes in 1 blocks
==4434== still reachable: 0 bytes in 0 blocks
==4434== suppressed: 0 bytes in 0 blocks
==4434==
==4434== For counts of detected and suppressed errors, rerun with: -v
==4434== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
And of course to try to include an answer to the question, exit(1) forces the program to quit without invoking any destructors, as far as I know--I've only been using C++ for a month and a half, so I'm not really an expert.
Perhaps the C++ class in question is doing something with pointers that suggests possibly leaky behavior to Valgrind.
I get diagnostics about this in a project in which I allocate some arrays, but then I adjust the pointer to the third element so that indices [-2] and [-1] are used to store some meta-information. There is no leak because I restore the pointer and free the arrays correctly.
Valgrind sees that the objects are referenced, however, that they are not referenced "nicely" via pointers to their base address, but only via interior pointers. It looks like a possible leak since no pointer exists for freeing the object.
A situation like this could happen in leaky programs: programs that, say, allocate a big object, give pieces of it (via pointers) to other modules, and then leak the big object. Interior pointers do suggest a leak.
It could be that getline is chummy with the representation of basic::string<> and does something of that sort. When you copy the object, the new object doesn't do anything funny: it just references the string data by its base address. The old object is gone, and it freed the data.
Just a hypothesis.
By the way, in that aforementioned program, I fixed things for Valgrind by retaining an extra pointer to the base address in the vector objects managing those arrays. This extra pointer is only present when the software is built for Valgrind debugging (along with other features, like use of the Valgrind client request API).

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.