Skip to content

Instantly share code, notes, and snippets.

@shurane
Last active August 29, 2015 14:25
Show Gist options
  • Save shurane/109c0c8ca79bbae68a86 to your computer and use it in GitHub Desktop.
Save shurane/109c0c8ca79bbae68a86 to your computer and use it in GitHub Desktop.
Confused at Invalid read of size 4?
$ clang++ -Wall -g --std=c++11 test-invalid-read.cpp -o test-invalid-read && valgrind --leak-check=yes ./test-invalid-read
==32099== Memcheck, a memory error detector
==32099== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==32099== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==32099== Command: ./test-invalid-read
==32099==
counter:0
counter:1
==32099== Invalid read of size 4
==32099== at 0x400EAC: Node::serialno() const (test-invalid-read.cpp:18)
==32099== by 0x400D70: operator<<(std::ostream&, Node const&) (test-invalid-read.cpp:24)
==32099== by 0x400E05: main (test-invalid-read.cpp:46)
==32099== Address 0x5a1c040 is 0 bytes inside a block of size 64 free'd
==32099== at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32099== by 0x4011AF: __gnu_cxx::new_allocator<Node>::deallocate(Node*, unsigned long) (new_allocator.h:110)
==32099== by 0x40112D: std::_Vector_base<Node, std::allocator<Node> >::_M_deallocate(Node*, unsigned long) (stl_vector.h:174)
==32099== by 0x4019AE: _ZNSt6vectorI4NodeSaIS0_EE19_M_emplace_back_auxIJjP12GraphManagerEEEvDpOT_ (stl_vector.h:430)
==32099== by 0x401595: _ZNSt6vectorI4NodeSaIS0_EE12emplace_backIJjP12GraphManagerEEEvDpOT_ (vector.tcc:101)
==32099== by 0x400F61: GraphManager::newNode() (test-invalid-read.cpp:34)
==32099== by 0x400DE4: main (test-invalid-read.cpp:43)
==32099==
Node(0)
Node(1)
==32099==
==32099== HEAP SUMMARY:
==32099== in use at exit: 0 bytes in 0 blocks
==32099== total heap usage: 2 allocs, 2 frees, 192 bytes allocated
==32099==
==32099== All heap blocks were freed -- no leaks are possible
==32099==
==32099== For counts of detected and suppressed errors, rerun with: -v
==32099== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
$
#include <vector>
#include <ostream>
#include <iostream>
class GraphManager;
class Node;
std::ostream& operator<<(std::ostream &strm, const Node& node);
class Node
{
int m_serialno;
GraphManager* m_gm;
std::vector<Node*> m_inedges;
std::vector<Node*> m_outedges;
public:
Node(int serialno, GraphManager* gm):
m_serialno(serialno), m_gm(gm) {}
// TODO what is wrong with this getter?
int serialno() const { return m_serialno; }
const std::vector<Node*>& inedges() const { return m_inedges; }
const std::vector<Node*>& outedges() const { return m_outedges; }
};
std::ostream& operator<<(std::ostream &strm, const Node& node) {
return strm << "Node(" << node.serialno() << ")";
}
class GraphManager
{
unsigned m_counter = 0;
std::vector<Node> m_nodes;
public:
Node* newNode() {
std::cout << "counter:" << m_counter << std::endl;
m_nodes.emplace_back(m_counter++, this);
return &m_nodes.back();
}
};
int main()
{
GraphManager gm;
auto n0 = gm.newNode();
auto n1 = gm.newNode();
/*auto n2 = gm.newNode();*/
/*auto n3 = gm.newNode();*/
std::cout << *n0 << std::endl;
std::cout << *n1 << std::endl;
/*std::cout << *n2 << std::endl;*/
/*std::cout << *n3 << std::endl;*/
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment