Pushing memory allocating objects into a vector.

H

hall

Hi.
I have some problems with a class i've written that allocates memory
dynamicaly. I want to put these objects into a std::vector, but it does
not work. My class looks (simplified) like this:

class Mem{
int *p, num;
public:
Mem(int a):p(0),n(a){
cout<< "created "<<num<<endl;
}
~Mem(){
if (p) delete []p;
cout << "destroyed "<<num<<endl;
}
void alloc(int i){
if (!p) p=new int;
}
};

My first attempt of creating a vector<Mem> was according to:

using namespace std;
int main(int argc, char* argv[])
{
vector<Mem> mv;
for (int i=0; i<3; i++){
cout << i<<endl;
Mem tmp(i);
tmp.alloc(10);
cout << "pushed"<<endl;
mv.push_back(tmp);
};
return 0;
}

However, this will not work as I create a temporary object tmp and lets
it allocate memory, then makes a bitwise copy of it that is pushed into
the vector. After this, tmp goes out of scope and deletes the memory it
had allocating, leaving the object in vector pointing to nonexisting
memory. Not good. (also, (not surprisingly) the program crashes, not
good at all)

So, how should i do this? My only present idea is to do something like:

vector<*Mem> ptrV;
for (int i=0; i<3; i++){
Mem *p=0;
ptrV.push_back(p);
ptrV = new Mem(i);
ptrV.alloc(10);
}
(written on the fly, so it might contain some errors, just to show the
idea...)


But this leaves the problem of memoryleaks if im not careful to delete
all allocated memory manually before clearing or overwriting the vector.
I know there is a better way of doing this, but have no idea of what it is.

Also, i'd appreciate if someone could explain the output of the main()
function above. The output to console is:
0
created 0
pushed
destroyed 0
1
created 1
pushed
destroyed 0
destroyed 1
2
created 2
pushed
destroyed 0
destroyed 1
destroyed 2
<Then, the program crashes>

On e.g. iteration 2, why is object 0, 1, and 2 destroyed? An explanation
would hopefully help me understand this copy-creation a little better.

cheers
hall
 
W

White Wolf

hall said:
Hi.
I have some problems with a class i've written that allocates memory
dynamicaly. I want to put these objects into a std::vector, but it
does not work. My class looks (simplified) like this:

class Mem{
int *p, num;
public:
Mem(int a):p(0),n(a){
cout<< "created "<<num<<endl;
}
~Mem(){
if (p) delete []p;
cout << "destroyed "<<num<<endl;
}
void alloc(int i){
if (!p) p=new int;
}
};


You need to implement a proper copy constructor and copy assigment operator.
Look up the rule of three.

WW aka Attila
 
S

Stephen Howe

So, how should i do this?

If your class allocates memory to a pointer within it, you need to write a
copy constructor and assignment operator.
vector requires that the containee is copy constructible and assignable.
Currently your class is not.

Stephen Howe
 
A

Attila Feher

White said:
hall wrote: [SNIP]
You need to implement a proper copy constructor and copy assigment
operator. Look up the rule of three.

http://c2.com/cgi/wiki?RuleOfThree

http://www.comp.lancs.ac.uk/computing/users/marash/SlidesCpp/slides/tsld067.
htm

Two descriptions of the rule of three. Basically what happens is that if
you have a pointer inside your class (pointing to something allocated by
your class) you need to manage that "hanging leaf" yourself:

On - An object of your class

An - The allocated thing

x - Nothing (NULL)

Mem O1;

O1 -> x

O1.alloc();

O1 -> A1

{Mem O2;

O1 -> A1
O2 -> x

O2.alloc();

O1 -> A1
O2 -> A2

O2 = O1 (something similar
happens inside the
vector during push_back)


O1 --> A1
O2 ----^
A2 (leaked memory)

} (scope closed, O2 is destructed)

O1 --> A1 (DELETED MEMORY!)

} (scope closed, O1 is destructed
and it tries to delete deleted
memory.)

BANG (if you are lucky.)

===

With the copy constructor the things will look a little bit different, but
not much. I hope this little "drawing" I made is understandable.
 
H

hall

Attila said:
White said:
hall wrote:
[SNIP]

You need to implement a proper copy constructor and copy assigment
operator. Look up the rule of three.


http://c2.com/cgi/wiki?RuleOfThree

http://www.comp.lancs.ac.uk/computing/users/marash/SlidesCpp/slides/tsld067.
htm

And why don't I know of this rule? I should, but I don't. Found rule of
two in Stroustups book, but that was something quite different. Ah well,
now i know it :).
With the copy constructor the things will look a little bit different, but
not much. I hope this little "drawing" I made is understandable.

Yes, it does. Thanks!

/hall
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top