Illegal memory access bug - c++

I have a bug which seems to cause access to memory which has already been cleared.
There are 2 classes - class B (which contains struct instances of class C and unique_ptrs of class D) and Class A which contains a vector of class B objects.
Here's the code structure of the area where the bug is caused:
void foo{
A localA(...);
bar(&localA);
baz(localA);
}
void bar(A* a) {
C c1 = constructLocalC1();
D d1 = constructLocalD1();
a.insertB(c1, &d1);
}
Note that insertB will call the constructor for class B - something like:
void A::insertB(C c, D* d) {
bVector.push_back(B(c, d));
}
B::B(C cIn, D* dIn) : c_(cIn) { d_ = make_unique<D>(*dIn); }
B {
public:
B(C c, D* d);
C c_;
std::unique_ptr<D> d_;
}
The implementation of constructLocalC1() looks something like (similar for constructLocalD1())
C constructLocalC1() {
C c1;
c1.blah = computeBlahParameter(); // blah is of type int
c1.bleh = computeBlehParameter(); // bleh is of type double
return c1;
}
The observation is that when baz tries to access (the copy of) c1 present in localA, the values in there are corrupted and not the same as the ones set by bar. My conclusion from this observation is that the vector which stores B is storing an element which has become de-allocated.
I know it is slightly complicated to understand the root cause through the code snippet here, as this is highly abstracted out - glad to provide more specific details which are required.
What are potential pitfalls and causes of memory leaks in this code snippet? What are good ways to approach the debugging?

Your problem probably is that you don't dynamically allocate memory on your objects inside bar.
If you create an object in a function that is not, explicitly or implicitly, dynamically allocated (using new, or by using temporary objects), then your objects are created on the stack, and they will be destroyed as soon as they come out of scope (in your case, when function returns). The one option is to allocate memory for the objects inserted in vector, but be extremely careful on memory handling and deallocation, as if not handled properly can result to memory leaks. You can also use smart pointers (Boost libraries have a great implementation of them but are also added on STL), that will prevent such situation, via RAII concept approach (For more on RAII, look on this topic: RAII and smart pointers in C++).

Related

How to delete part of a class?

The problem is quite simple. I have a class that can be structured as the following:
class MyClass {
struct A {
// ...
};
struct B {
// ...
};
};
The problem is: the information in MyClass::B is useless after some time of precomputations, whereas MyClass::A must never be deleted (the program may be running for days). MyClass::B holds quite a large amount of information. I want to get rid of MyClass::B while keeping MyClass::A in the same memory position.
Is it possible to do this without modifying too much the data structure and not having to add anything else to MyClass::A (in particular, a pointer to MyClass::B)? If so, what would be the right way to implement it? Take in account that the program must be as memory-efficient as possible (and let us take that to the extreme). I use C++14 BTW.
(And extra question: It is possible to delete the chunk corresponding to MyClass::B from MyClass?)
First or all that's a class declaration. You can't delete a part of the class declaration. You probably have something more like this:
// The exact place of the declaration doesn't matter actually
class A {...};
class B {...};
class C {
A a;
B b;
};
Just change it to use a pointer (in this day and age a smart pointer, like std::unique_ptr):
class C {
A a;
std::unique_ptr<B> b;
void FinishTaskThatRequiredB() {
b.reset(); // calls B::~B() and frees the memory.
}
};
Okay, let's elaborate a bit on what I wrote: “either the life of B is tied to that of MyClass, or it is independent. In that latter case, you must keep track of it in some way”.
Putting the context back from the question:
MyClass::B is useless after some time of precomputations.
MyClass::A must never be deleted.
Is ensues that you want to keep track of it in some way. How? Well, that depends on the rules on the life time.
If B could sometimes exist and sometimes not depending on hard to control (or plain unknowable) circumstances, then having a pointer to it, set to nullptr when it is useless, and dynamically allocated when it is useful is pretty much the only solution.
But here we have more knowledge: B exists first, then becomes useless and remains so forever. In other terms, you don't need B after some initial building steps used to create A.
There is a pattern that does exactly this: the builder pattern. Its purpose is to encapsulate a complex building operation, maybe tracking some state, until it has built some object, at which point it becomes useless and can be destroyed.
class ABuilder
{
public:
setSomeInfo(int);
doSomeComputation(......);
// etc
A get(); /// finalize building of A
private:
int someInfo_ = 0;
};
// somewhere else
auto b = ABuilder();
b.setSomeInfo(42);
b.doSomeComputation(......);
auto a = b.get();
// b is no longer used past that point
// delete it if it was allocated dynamically
// or let it go out of scope if it was automatic
From your example, it would map somewhat like this:
A is still A.
B is ABuilder.
MyClass is not needed.
If you had provided actual class names and purpose, it would have been easier to make the examples meaningful ;)
In any case, pointers are most likely the key to your desires. In any case, too, you need to separate B from MyClass, too. You can avoid a pointer within MyClass (see comments to question and other answer), if you store B separately and invert the direction of the pointer:
class MyClass
{
struct A { };
A a;
};
class Wrapper
{
struct B { };
MyClass* mc;
B b;
};
Now during initialisation, you'd create a Wrapper for each MyClass, most likely contained in two different arrays:
MyClass items[NUMBER_OF_ITEMS]; // global array?
Wrapper* wrappers = new Wrapper[NUMBER_OF_ITEMS];
// assign each item to its corresponding wrapper
// use the wrappers for initialisation
delete[] wrappers;
Now all that remains is one single pointer, of which you even might get rid if it is a local variable in a separate initialisation routine...

Is it mandatory to delete a pointer variable within a structure, before deleting the structure?

I have started to C++ and need some clarifications regarding memory management in C++. I have come across smart pointers, but I wish to understand some basic concepts.
Here's a sample structure
struct A
{
private:
int a;
void* b;
public:
A(int i, void* m) { a=i; b=m; }
};
main()
{
A * a1 = new A(10, 0);
//
//Some Code
if(on some condition) {
delete a1;
a1=nullptr;
}
}
When I delete a1, will m also be deleted automatically or should i explicitly delete m before deleting a1 as given below?
delete a1->b;
a1->b = nullptr;
delete a1;
a1=nullptr;
When I delete a1, will m also be deleted automatically
No, it won't (your code probably has a memory leak). You need an explicit destructor deleting it.
BTW, using a void*b; pointer field is poor taste. You should prefer some more explicit type (e.g. double*b; or SomeClass* b;) if you know it. This makes your code more readable, and give more opportunities for helpful type checking at compile time.
// inside struct A
~A() { delete b; };
Read about the rule of five.
Notice that struct-s are very similar to class-es in C++.
Avoid memory leaks. Tools like valgrind could be helpful. And using systematically smart pointers and standard containers should help to avoid them. If your field b was declared std::shared_ptr<std::string> b; the default destructor would have freed it appropriately. And perhaps you want it to be some std::vector<std::string> (again, the default destructor is releasing memory appropriately).
A good coding hint is to avoid, when possible, declaring raw pointers (prefer smart pointers and containers). When you have to declare one, you need to code its delete appropriately.
Welcome to C++, a very powerful language that requires you to take responsibility of the details to achieve the flexibility that allows such power. If you like, you can make it very complex, however for most constructs their is an easy way as well.
First of all, you ain't required to release memory, if your program exits, it will clean it. However, as you don't call delete, the Dtor will not be called which might cause specific code to not be executed.
So in general, it's good practice to clean up the allocated memory.
If you don't need the heap, don't use it
new A(10, 0) will allocate memory on the heap. If you don't want that, this can as well be created on the stack. Which causes auto cleanup: A a{10, nullptr};
Use RAII
As soon as you decide, you need heap allocated memory, you should default to std::unique_ptr. Which changes the code to: auto a = std::make_unique<A>(10, nullptr); With this, ownership is within the unique_ptr, which can be moved around (std::move). If you don't want to transfer ownership, you can dereference it or call the method get.
Applying these 2 practices, including for members, will prevent a lot of memory leaks and will reduce the time you need to think about it.
Don't use void*
void* is evil, don't use it unless you have to (and you only have to when interfacing with C). There are many ways of avoiding it. The best one is introducing an interface.
class I {
public:
virtual ~I() = default;
};
class M : public I
{
// ...
};
class A
{
// ...
std::unique_ptr<I> m;
// ...
};
Need something special?
Some times, you need something special in the Dtor, only in that case you should implement the Dtor explicitly. Given your question, I'm gonna assume you are a beginner and as such don't need to know about more details for now.

Is it necessary to use 'delete' on pointers before assigning different value?

This might be a silly question but I am not sure what is the correct way of doing this (searching did not yield definitive answer for me).
Consider following snippet:
class D;
class C
{
C() {m_Ptr = new D;};
~C() {delete m_Ptr;};
public:
void setPtr(const D &obj) {*m_Ptr = obj};
private:
D *m_Ptr;
};
Is it okay to simply assign new value to *m_Ptr even though it already points to a different object of class D? I tend to use:
void C::setPtr(const D &obj)
{
delete m_Ptr;
*m_Ptr = obj;
}
but I am not sure if that is necessary or good/bad practice. My reasoning is that every 'new' should have its 'delete' (or other means of deallocating memory such as parent-child mechanism in Qt).
Thanks for clarification!
You might need to do delete if you reassign the pointer. In your case you don't do that, you just change the data pointed to by the pointer.
In fact, doing e.g.
delete m_Ptr;
*m_Ptr = obj;
would lead to undefined behavior as you dereference the pointer after you free the memory it pointed to, and you then write to memory you no longer "own".
There is a deeper problem than what you're facing now.
void setPtr(const D &obj) {*m_Ptr = obj};
How do you know if obj is an object created by new? How can you make sure the caller intends that C call delete on its address? What you are doing is bad class design, and there is a much better solution to it that both addresses your current issue and what I'm fussing about.
Make sure first that you have read What is The Rule of Three?
So, how can you make your class design better? Use the Rule of Three! Provide copy (and if available move) constructors and assignment operators. After you have done this, remove setPtr. setPtr is a bad thing. Provide a constructor instead that copies an existing D object. In this way, you insulate the details on how you create what is pointed by m_Ptr.
C(D& d) {m_Ptr = new D(d); };
You should also provide an appropriate copy constructor for D. To use it, instead of
C x;
D* y = new D;
x.setPtr(*D);
you do
C x = D();
// or
C x;
x = C(D());
Do you want C to hold a D depending on some parameters? Maybe they are parameters to D's constructor(s)? You could provide a "named constructor":
class C {
static C createBlah(int x, float y) {
C c = D(x, y);
return c;
}
};
// Using it...
C c = C::createBlah(42, 3.14f);
So now, the users of your class C doesn't have to worry about anything concerning D. Why put the burden on them? Why have them use new when it'll put them in grave danger? Why make the world more miserable?!
There, that's better.
UPDATE: Much better though, make the D object directly as a member, instead of a pointer to it. #Peter's comment pretty much sums up the point.
Every time you new something you have to delete it. This rule is only really broken with something like the std smart pointers which delete the memory for you.
HOWEVER in your example you're simply filling the memory at m_Ptr with the memory that's at obj. So, deleting here would cause problems.
EDIT: As Peter said in the comments, you're far better off storing a D object on the class. Avoid unnecessary pointers like this as much as you can.

Why doesn't polymorphism work without pointers/references?

I did find some questions already on StackOverflow with similar title, but when I read the answers, they were focusing on different parts of the question, which were really specific (e.g. STL/containers).
Could someone please show me, why you must use pointers/references for implementing polymorphism? I can understand pointers may help, but surely references only differentiate between pass-by-value and pass-by-reference?
Surely so long as you allocate memory on the heap, so that you can have dynamic binding, then this would have been enough. Obviously not.
"Surely so long as you allocate memory on the heap" - where the memory is allocated has nothing to do with it. It's all about the semantics. Take, for instance:
Derived d;
Base* b = &d;
d is on the stack (automatic memory), but polymorphism will still work on b.
If you don't have a base class pointer or reference to a derived class, polymorphism doesn't work because you no longer have a derived class. Take
Base c = Derived();
The c object isn't a Derived, but a Base, because of slicing. So, technically, polymorphism still works, it's just that you no longer have a Derived object to talk about.
Now take
Base* c = new Derived();
c just points to some place in memory, and you don't really care whether that's actually a Base or a Derived, but the call to a virtual method will be resolved dynamically.
In C++, an object always has a fixed type and size known at compile-time and (if it can and does have its address taken) always exists at a fixed address for the duration of its lifetime. These are features inherited from C which help make both languages suitable for low-level systems programming. (All of this is subject to the as-if, rule, though: a conforming compiler is free to do whatever it pleases with code as long as it can be proven to have no detectable effect on any behavior of a conforming program that is guaranteed by the standard.)
A virtual function in C++ is defined (more or less, no need for extreme language lawyering) as executing based on the run-time type of an object; when called directly on an object this will always be the compile-time type of the object, so there is no polymorphism when a virtual function is called this way.
Note that this didn't necessarily have to be the case: object types with virtual functions are usually implemented in C++ with a per-object pointer to a table of virtual functions which is unique to each type. If so inclined, a compiler for some hypothetical variant of C++ could implement assignment on objects (such as Base b; b = Derived()) as copying both the contents of the object and the virtual table pointer along with it, which would easily work if both Base and Derived were the same size. In the case that the two were not the same size, the compiler could even insert code that pauses the program for an arbitrary amount of time in order to rearrange memory in the program and update all possible references to that memory in a way that could be proven to have no detectable effect on the semantics of the program, terminating the program if no such rearrangement could be found: this would be very inefficient, though, and could not be guaranteed to ever halt, obviously not desirable features for an assignment operator to have.
So in lieu of the above, polymorphism in C++ is accomplished by allowing references and pointers to objects to reference and point to objects of their declared compile-time types and any subtypes thereof. When a virtual function is called through a reference or pointer, and the compiler cannot prove that the object referenced or pointed to is of a run-time type with a specific known implementation of that virtual function, the compiler inserts code which looks up the correct virtual function to call a run-time. It did not have to be this way, either: references and pointers could have been defined as being non-polymorphic (disallowing them to reference or point to subtypes of their declared types) and forcing the programmer to come up with alternative ways of implementing polymorphism. The latter is clearly possible since it's done all the time in C, but at that point there's not much reason to have a new language at all.
In sum, the semantics of C++ are designed in such a way to allow the high-level abstraction and encapsulation of object-oriented polymorphism while still retaining features (like low-level access and explicit management of memory) which allow it to be suitable for low-level development. You could easily design a language that had some other semantics, but it would not be C++ and would have different benefits and drawbacks.
I found it helpful to understand that a copy constructor is invoked when assigning like this:
class Base { };
class Derived : public Base { };
Derived x; /* Derived type object created */
Base y = x; /* Copy is made (using Base's copy constructor), so y really is of type Base. Copy can cause "slicing" btw. */
Since y is an actual object of class Base, rather than the original one, functions called on this are Base's functions.
Consider little endian architectures: values are stored low-order-bytes first. So, for any given unsigned integer, the values 0-255 are stored in the first byte of the value. Accessing the low 8-bits of any value simply requires a pointer to it's address.
So we could implement uint8 as a class. We know that an instance of uint8 is ... one byte. If we derive from it and produce uint16, uint32, etc, the interface remains the same for purposes of abstraction, but the one most important change is size of the concrete instances of the object.
Of course, if we implemented uint8 and char, the sizes may be the same, likewise sint8.
However, operator= of uint8 and uint16 are going to move different quantities of data.
In order to create a Polymorphic function we must either be able to:
a/ receive the argument by value by copying the data into a new location of the correct size and layout,
b/ take a pointer to the object's location,
c/ take a reference to the object instance,
We can use templates to achieve a, so polymorphism can work without pointers and references, but if we are not counting templates, then lets consider what happens if we implement uint128 and pass it to a function expecting uint8? Answer: 8 bits get copied instead of 128.
So what if we made our polymorphic function accept uint128 and we passed it a uint8. If our uint8 we were copying was unfortunately located, our function would attempt to copy 128 bytes of which 127 were outside of our accessible memory -> crash.
Consider the following:
class A { int x; };
A fn(A a)
{
return a;
}
class B : public A {
uint64_t a, b, c;
B(int x_, uint64_t a_, uint64_t b_, uint64_t c_)
: A(x_), a(a_), b(b_), c(c_) {}
};
B b1 { 10, 1, 2, 3 };
B b2 = fn(b1);
// b2.x == 10, but a, b and c?
At the time fn was compiled, there was no knowledge of B. However, B is derived from A so polymorphism should allow that we can call fn with a B. However, the object it returns should be an A comprising a single int.
If we pass an instance of B to this function, what we get back should be just a { int x; } with no a, b, c.
This is "slicing".
Even with pointers and references we don't avoid this for free. Consider:
std::vector<A*> vec;
Elements of this vector could be pointers to A or something derived from A. The language generally solves this through the use of the "vtable", a small addition to the object's instance which identifies the type and provides function pointers for virtual functions. You can think of it as something like:
template<class T>
struct PolymorphicObject {
T::vtable* __vtptr;
T __instance;
};
Rather than every object having its own distinct vtable, classes have them, and object instances merely point to the relevant vtable.
The problem now is not slicing but type correctness:
struct A { virtual const char* fn() { return "A"; } };
struct B : public A { virtual const char* fn() { return "B"; } };
#include <iostream>
#include <cstring>
int main()
{
A* a = new A();
B* b = new B();
memcpy(a, b, sizeof(A));
std::cout << "sizeof A = " << sizeof(A)
<< " a->fn(): " << a->fn() << '\n';
}
http://ideone.com/G62Cn0
sizeof A = 4 a->fn(): B
What we should have done is use a->operator=(b)
http://ideone.com/Vym3Lp
but again, this is copying an A to an A and so slicing would occur:
struct A { int i; A(int i_) : i(i_) {} virtual const char* fn() { return "A"; } };
struct B : public A {
int j;
B(int i_) : A(i_), j(i_ + 10) {}
virtual const char* fn() { return "B"; }
};
#include <iostream>
#include <cstring>
int main()
{
A* a = new A(1);
B* b = new B(2);
*a = *b; // aka a->operator=(static_cast<A*>(*b));
std::cout << "sizeof A = " << sizeof(A)
<< ", a->i = " << a->i << ", a->fn(): " << a->fn() << '\n';
}
http://ideone.com/DHGwun
(i is copied, but B's j is lost)
The conclusion here is that pointers/references are required because the original instance carries membership information with it that copying may interact with.
But also, that polymorphism is not perfectly solved within C++ and one must be cognizant of their obligation to provide/block actions which could produce slicing.
You need pointers or reference because for the kind of polymorphism you are interested in (*), you need that the dynamic type could be different from the static type, in other words that the true type of the object is different than the declared type. In C++ that happens only with pointers or references.
(*) Genericity, the type of polymorphism provided by templates, doesn't need pointers nor references.
When an object is passed by value, it's typically put on the stack. Putting something on the stack requires knowledge of just how big it is. When using polymorphism, you know that the incoming object implements a particular set of features, but you usually have no idea the size of the object (nor should you, necessarily, that's part of the benefit). Thus, you can't put it on the stack. You do, however, always know the size of a pointer.
Now, not everything goes on the stack, and there are other extenuating circumstances. In the case of virtual methods, the pointer to the object is also a pointer to the object's vtable(s), which indicate where the methods are. This allows the compiler to find and call the functions, regardless of what object it's working with.
Another cause is that very often the object is implemented outside of the calling library, and allocated with a completely different (and possibly incompatible) memory manager. It could also have members that can't be copied, or would cause problems if they were copied with a different manager. There could be side-effects to copying and all sorts of other complications.
The result is that the pointer is the only bit of information on the object that you really properly understand, and provides enough information to figure out where the other bits you need are.

C++ question about setting class variables

I'm not new to programming, but after working in Java I'm coming back to C++ and am a little confused about class variables that aren't pointers. Given the following code:
#include <iostream>
#include <map>
using namespace std;
class Foo {
public:
Foo() {
bars[0] = new Bar;
bars[0]->id = 5;
}
~Foo() { }
struct Bar {
int id;
};
void set_bars(map<int,Bar*>& b) {
bars = b;
}
void hello() {
cout << bars[0]->id << endl;
}
protected:
map<int,Bar*> bars;
};
int main() {
Foo foo;
foo.hello();
map<int,Foo::Bar*> testbars;
testbars[0] = new Foo::Bar;
testbars[0]->id = 10;
foo.set_bars(testbars);
foo.hello();
return(0);
}
I get the expected output of 5 & 10. However, my lack of understanding about references and pointers and such in C++ make me wonder if this will actually work in the wild, or if once testbars goes out of scope it will barf. Of course, here, testbars will not go out of scope before the program ends, but what if it were created in another class function as a function variable? Anyway, I guess my main question is would it better/safer for me to create the bars class variable as a pointer to the map map?
Anyway, I guess my main question is
would it better/safer for me to create
the bars class variable as a pointer
to the map map?
No. C++ is nothing like Java in this and may other respects. If you find yourself using pointers and allocating new'd objects to them a lot, you are probably doing something wrong. To learn the right way to do things, I suggest getting hold of a copy of Accelerated C++ by Koenig & Moo,
The member variable bars is a separate instance of a "dictionary"-like/associative array class. So when it is assigned to in set_bars, the contents of the parameter b are copied into bars. So there is no need to worry about the relative lifetimes of foo and testbars, as they are independent "value-like" entites.
You have more of a problem with the lifetimes of the Bar objects, which are currently never going to be deleted. If you add code somewhere to delete them, then you will introduce a further problem because you are copying the addresses of Bar objects (rather than the objects themselves), so you have the same object pointed to by two different maps. Once the object is deleted, the other map will continue to refer to it. This is the kind of thing that you should avoid like the plague in C++! Naked pointers to objects allocated with new are a disaster waiting to happen.
References (declared with &) are not different from pointers with regard to object lifetimes. To allow you to refer to the same object from two places, you can use either pointers or references, but this will still leave you with the problem of deallocation.
You can get some way toward solving the deallocation problem by using a class like shared_ptr, which should be included with any up-to-date C++ environment (in std::tr1). But then you may hit problems with cyclical pointer networks (A points to B and B points to A, for example), which will not be automatically cleaned up.
For every new you need a corresponding delete.
If you try and reference the memory after you call delete - where ever that is - then the program will indeed "barf".
If you don't then you will be fine, it's that simple.
You should design your classes so that ownership of memory is explicit, and that you KNOW that for every allocation you are doing an equal deallocation.
Never assume another class/container will delete memory you allocated.
Hope this helps.
In the code below you can pass map of Bars and then will be able to modify Bars outside of the class.
But. But unless you call set_bars again.
It is better when one object is responsible for creation and deletion of Bars. Which is not true in your case.
If you want you can use boost::shared_ptr< Bars > instead of Bars*. That will be more Java like behavior.
class Foo {
public:
Foo() {
bars[0] = new Bar;
bars[0]->id = 5;
}
~Foo() { freeBarsMemory(); }
struct Bar {
int id;
};
typedef std::map<int,Bar*> BarsList;
void set_bars(const BarsList& b) {
freeBarsMemory();
bars = b;
}
void hello() {
std::cout << bars[0]->id << std::endl;
}
protected:
BarsList bars;
void freeBarsMemory()
{
BarsList::const_iterator it = bars.begin();
BarsList::const_iterator end = bars.end();
for (; it != end; ++it)
delete it->second;
bars.clear();
}
};
I'm not new to programming, but after working in Java I'm coming back to C++ and am a little confused about class variables that aren't pointers.
The confusion appears to come from a combination of data that is on the heap and data that is not necessarily on the heap. This is a common cause of confusion.
In the code you posted, bars is not a pointer. Since it's in class scope, it will exist until the object containing it (testbars) is destroyed. In this case testbars was created on the stack so it will be destroyed when it falls out of scope, regardless of how deeply nested that scope is. And when testbars is destroyed, subobjects of testbars (whether they are parent classes or objects contained within the testbars object) will have their destructors run at that exact moment in a well-defined order.
This is an extremely powerful aspect of C++. Imagine a class with a 10-line constructor that opens a network connection, allocates memory on the heap, and writes data to a file. Imagine that the class's destructor undoes all of that (closes the network connection, deallocates the memory on the heap, closes the file, etc.). Now imagine that creating an object of this class fails halfway through the constructor (say, the network connection is down). How can the program know which lines of the destructor will undo the parts of the constructor that succeeded? There is no general way to know this, so the destructor of that object is not run.
Now imagine a class that contains ten objects, and the constructor for each of those objects does one thing that must be rolled back (opens a network connection, allocates memory on the heap, writes data to a file, etc.) and the destructor for each of those objects includes the code necessary to roll back the action (closes the network connection, deallocates objects, closes the file, etc.). If only five objects are successfully created then only those five need to be destroyed, and their destructors will run at that exact moment in time.
If testbars had been created on the heap (via new) then it would only be destroyed when calling delete. In general it's much easier to use objects on the stack unless there is some reason for the object to outlast the scope it was created in.
Which brings me to Foo::bar. Foo::bars is a map that refers to objects on the heap. Well, it refers to pointers that, in this code example, refer to objects allocated on the heap (pointers can also refer to objects allocated on the stack). In the example you posted the objects these pointers refer to are never deleted, and because these objects are on the heap you're getting a (small) memory leak (which the operating system cleans up on program exit). According to the STL, std::maps like Foo::bar do not delete pointers they refer to when they are destroyed. Boost has a few solutions to this problem. In your case it's probably be easiest to simply not allocate these objects on the heap:
#include <iostream>
#include <map>
using std::map;
using std::cout;
class Foo {
public:
Foo() {
// normally you wouldn't use the parenthesis on the next line
// but we're creating an object without a name, so we need them
bars[0] = Bar();
bars[0].id = 5;
}
~Foo() { }
struct Bar {
int id;
};
void set_bars(map<int,Bar>& b) {
bars = b;
}
void hello() {
cout << bars[0].id << endl;
}
protected:
map<int,Bar> bars;
};
int main() {
Foo foo;
foo.hello();
map<int,Foo::Bar> testbars;
// create another nameless object
testbars[0] = Foo::Bar();
testbars[0].id = 10;
foo.set_bars(testbars);
foo.hello();
return 0;
}