473,739 Members | 2,531 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Storing objects in vectors - what's wrong with this code?

I have written the following code, to test the concept of storing
objects in a vector. I encounter two run time errors:

1). myClass gets destructed when pushed onto the vector
2). Prog throws a "SEGV" when run (presumably - attempt to delete
deleted memory.

Please take a look and see if you can notice any mistakes I'm making.
Basically, I want to store classes of my objects in a vector. I also
have three further questions:

1). What happens to my objects when erase() or clear() is invoked on the
container vector?

2). What is the best way to create new objects for pushing on to the
vector (the new keyword returns a pointer to the class - which suggests
I should probably be storing *pointers* to the class rather than the
class itself? - but push_back() has signature push_back(const T&) - I'm
confused)

3). Do I have to manually handle destruction of my objects when:

(a) pop_back is invoked on the vector (in this case what happens to my
last element?)
(b). The vector is resized (who frees my objects at the end?)
(c). The vector goes out of scope and its destructor is called?
Here is the code snippet mentioned previously:

#include <vector>
#include <iostream>

using namespace std ;

class MyClass {
public:
MyClass(){
cout << "cstor called !" << endl ;
i = new int ;
*i = 100 ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}

int getVal(void){ return *i ; }
void setVal(int v){ *i=v ;}

private:
int* i ;
};

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyC lass> mv ;

mv.push_back(mc ) ; // Crashes here. Also I want to store
// a dynamic number of objects in the
// vector. How may I do this?
mv.clear ;
return 0;
}

Jul 23 '05 #1
6 2576
> I have written the following code, to test the concept of storing
objects in a vector. I encounter two run time errors:

1). myClass gets destructed when pushed onto the vector
2). Prog throws a "SEGV" when run (presumably - attempt to delete
deleted memory.

Please take a look and see if you can notice any mistakes I'm making.
Basically, I want to store classes of my objects in a vector. I also
have three further questions:

1). What happens to my objects when erase() or clear() is invoked on the
container vector?

2). What is the best way to create new objects for pushing on to the
vector (the new keyword returns a pointer to the class - which suggests
I should probably be storing *pointers* to the class rather than the
class itself? - but push_back() has signature push_back(const T&) - I'm
confused)

3). Do I have to manually handle destruction of my objects when:

(a) pop_back is invoked on the vector (in this case what happens to my
last element?)
(b). The vector is resized (who frees my objects at the end?)
(c). The vector goes out of scope and its destructor is called?
Here is the code snippet mentioned previously:

#include <vector>
#include <iostream>

using namespace std ;

class MyClass {
public:
MyClass(){
cout << "cstor called !" << endl ;
i = new int ;
*i = 100 ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}

int getVal(void){ return *i ; }
void setVal(int v){ *i=v ;}

private:
int* i ;
};

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyC lass> mv ;

mv.push_back(mc ) ; // Crashes here. Also I want to store
// a dynamic number of objects in the
// vector. How may I do this?
mv.clear ;
return 0;
}


You need to provide a copy constructor. A default copy constructor is used
so a copied MyClass will share the same inner i, which, when deleted, will
cause problems.

ben
Jul 23 '05 #2
Alfonso Morra wrote:
I have written the following code, to test the concept of storing
objects in a vector. I encounter two run time errors:

1). myClass gets destructed when pushed onto the vector
2). Prog throws a "SEGV" when run (presumably - attempt to delete
deleted memory.

Please take a look and see if you can notice any mistakes I'm making.
Basically, I want to store classes of my objects in a vector. I also
have three further questions:

1). What happens to my objects when erase() or clear() is invoked on the
container vector?
Since what you have in a vector is a copy of your elements, calling
erase() or clear() in a vector does not have any effects on your
variables (which are obviously not vector elements but a copy of it).
2). What is the best way to create new objects for pushing on to the
vector (the new keyword returns a pointer to the class - which suggests
I should probably be storing *pointers* to the class rather than the
class itself? - but push_back() has signature push_back(const T&) - I'm
confused)
No

std::vector<MyC lass> mv ;

defines a vector mv which can accomodate 'MyClass' objects, and what
you are pushing in the vactor is mc which is a MyClass object, which is
absolutely fine. So, far so good.
3). Do I have to manually handle destruction of my objects when:

(a) pop_back is invoked on the vector (in this case what happens to my
last element?)
pop_back() returns a copy of the last element from a vector, the
original copy from the vector has been deleted. So, all the local
objects will automatically get deleted. I don't see anywhere new
(outside class MyClass), so no question of manually destructing
objects.
(b). The vector is resized (who frees my objects at the end?)
When the vector gets resized is the the vectors job to efficiently move
elements and destroy any temporaraies created during this job, so you
are not the one who really needs to worry about it, unless you are
writing a vector ofcourse.
(c). The vector goes out of scope and its destructor is called?

When a vector goes out of scope, its destructor calls destructors for
all of its elements, so all the cleanup is supposed to be done by the
vector.
You have problem somewhere else. See my comments below:

Here is the code snippet mentioned previously:

#include <vector>
#include <iostream>

using namespace std ;

class MyClass {
public:
MyClass(){
cout << "cstor called !" << endl ;
i = new int ;
*i = 100 ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}
If you think, you need any one of copy constructor, assignment operator
and destructor, you need all of these.

Define a copy constructor and an assignment operator
MyClass ( const MyClass& m ) {
i = new int;
*i = m.getVal();
}
MyClass& operator= ( const MyClass& m ) {
i = new int;
*i = m.getVal();
return *this;
}
int getVal(void){ return *i ; }
Define getVal() before the copy constructor as it uses it.
void setVal(int v){ *i=v ;}

private:
int* i ;
Your class has a char*, you need a suitable copy constructor. };

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyC lass> mv ;

mv.push_back(mc ) ; // Crashes here. Also I want to store
// a dynamic number of objects in the
// vector. How may I do this?
mv.clear ;
return 0;
}


Since there was not a copy constructor, the default copy constructor
copies the pointers while copying i. So, after the copy, both objects
point to the same memory location created in constructor using new.
This is bad, because when one gets out of scope, its destructor gets
called, which frees up to allocated memory. The otherone's i is still
pointing to the same memory this is a disaster.

/P

Jul 23 '05 #3


pk******@gmail. com wrote:
Alfonso Morra wrote:
I have written the following code, to test the concept of storing
objects in a vector. I encounter two run time errors:

1). myClass gets destructed when pushed onto the vector
2). Prog throws a "SEGV" when run (presumably - attempt to delete
deleted memory.

Please take a look and see if you can notice any mistakes I'm making.
Basically, I want to store classes of my objects in a vector. I also
have three further questions:

1). What happens to my objects when erase() or clear() is invoked on the
container vector?

Since what you have in a vector is a copy of your elements, calling
erase() or clear() in a vector does not have any effects on your
variables (which are obviously not vector elements but a copy of it).

You seem to misunderstand my question. Granted, the objects in the
vector are copies of the originals. My question was that what happens to
the objects *in the vector container* when a clear() or erase() is
called - do they get freed?

On a slightly different note - since a vector stores a copy of the item
to be stored, it behooves me to delete the original copy(ies) , since I
do not want two copies, floating about - maybe it would be better to
store pointers to my object instead?. It seems quite
inefficient/expensive of going through the steps of:

i). Object creation
ii). Making copy of the object
iii). Deleting the original object (so only the copy in the vector is kept)

It just dosen't seem right ...
2). What is the best way to create new objects for pushing on to the
vector (the new keyword returns a pointer to the class - which suggests
I should probably be storing *pointers* to the class rather than the
class itself? - but push_back() has signature push_back(const T&) - I'm
confused)


No

std::vector<MyC lass> mv ;

defines a vector mv which can accomodate 'MyClass' objects, and what
you are pushing in the vactor is mc which is a MyClass object, which is
absolutely fine. So, far so good.

3). Do I have to manually handle destruction of my objects when:

(a) pop_back is invoked on the vector (in this case what happens to my
last element?)

pop_back() returns a copy of the last element from a vector, the
original copy from the vector has been deleted. So, all the local
objects will automatically get deleted. I don't see anywhere new
(outside class MyClass), so no question of manually destructing
objects.

(b). The vector is resized (who frees my objects at the end?)

When the vector gets resized is the the vectors job to efficiently move
elements and destroy any temporaraies created during this job, so you
are not the one who really needs to worry about it, unless you are
writing a vector ofcourse.

(c). The vector goes out of scope and its destructor is called?

When a vector goes out of scope, its destructor calls destructors for
all of its elements, so all the cleanup is supposed to be done by the
vector.
You have problem somewhere else. See my comments below:


Thanks for the correction and pointers
/P


Jul 23 '05 #4
Remember the rule of 3:
If there's a need to define the destructor of a class,
you'll also need to provide the copy constructor
and the assignment operator.

regards, Stephan

Jul 23 '05 #5
Alfonso Morra wrote:


pktiwary at gmail.com wrote:
Since what you have in a vector is a copy of your elements, calling
erase() or clear() in a vector does not have any effects on your
variables (which are obviously not vector elements but a copy of it).

You seem to misunderstand my question. Granted, the objects in the
vector are copies of the originals. My question was that what happens to
the objects *in the vector container* when a clear() or erase() is
called - do they get freed?


I think that would probably depend on the allocator of the vector, but generally, I suspect the destructor is called, and the memory freed.
On a slightly different note - since a vector stores a copy of the item
to be stored, it behooves me to delete the original copy(ies) , since I
do not want two copies, floating about - maybe it would be better to
store pointers to my object instead?. It seems quite
inefficient/expensive of going through the steps of:

i). Object creation
ii). Making copy of the object
iii). Deleting the original object (so only the copy in the vector is kept)

It just dosen't seem right ...


1) You could let the original go out of scope... depending on what you do with this, I suspect the compiler will optimise the copy.

2) You could create the original directly in the vector:

mv.push_back(My Class());

//Although on VS .NET you still get 1 construction, presumably two copies and 3 destructions whether you use the temporory or not.

2). What is the best way to create new objects for pushing on to the
vector (the new keyword returns a pointer to the class - which suggests
I should probably be storing *pointers* to the class rather than the
class itself? - but push_back() has signature push_back(const T&) - I'm
confused)


MyClass is a type
MyClass* is also a completely valid, different type.

You can do:

std::vector<MyC lass*> mv;

If you like, but it means keeping track of your pointers, so don't do this:
mv.push_back(ne w MyClass());

And definately don't try to use an auto_ptr to manage it.

Also, I fail to see the point of having your int member of MyClass a pointer, whats wrong with:

class MyClass {
public:
MyClass() : i(100) {
cout << "cstor called !" << endl ;
}

virtual ~MyClass(){
cout << "dstor called !" << endl ;
}

int getVal(void){ return i ; }
void setVal(int v){ i=v ;}

private:
int i;
};

In that case the compiler provided copy and assignment will be fine.

Ben
--
I'm not just a number. To many, I'm known as a String...
Jul 23 '05 #6
Alfonso Morra wrote:
I have written the following code, to test the concept of storing
objects in a vector. I encounter two run time errors:

1). myClass gets destructed when pushed onto the vector
MyClass is a class, not an object. It cannot be destructed. In the code
below, nothing is supposed to get destroyed on the line

mv.push_back(mc ) ;
2). Prog throws a "SEGV" when run (presumably - attempt to delete
deleted memory.
Yes, that's not surprising.
Please take a look and see if you can notice any mistakes I'm making.
Basically, I want to store classes of my objects in a vector. I also
No, you want to store MyClass objects in the vector. Be careful with
names!
have three further questions:

1). What happens to my objects when erase() or clear() is invoked on the
container vector?
Depends on what you mean by 'my objects'. A std::vector manages its
memory and its elements. For example:

std::vector<int > v;
for (int i=0; i<10; ++i)
v.push_back(i);

Here, when the vector goes out of scope, it will manage its ten ints.
That means you don't have to worry about it. A vector will usually be
implemented with a dynamic array, which means it will delete the its
memory with delete[], which will call the destructors for all the
objects.

Now, it does the same thing for pointers. The problem with pointers is
that they usually point to something which must be manually deleted. So
the vector will destroy all the pointers correctly, but not the objects
pointed at. You'll have to do this manually.

int main()
{
std::vector<int *> v;
for (int i=0; i<10; ++i)
v.push_back(new int(i));

// v will leak the ints if you dont do that:
for (int i=0; i<10; ++i)
delete v[i];

// but v will never leak the pointers you pushed
}

2). What is the best way to create new objects for pushing on to the
vector
Depends. If you don't want copies to be made (for example, if the
objects are really big to copy, or if the identity of each object is
important), you'll want to store pointers. Since you are storing
pointers, you will need the object pointed at to last longer than
usual: you'll need dynamic memory.

If you can make copy as you wish, put objects by value in the
containers. It may seem 'inefficient', but it will save you a lot of
trouble.
(the new keyword returns a pointer to the class -
The new keyword return a pointer to a newly allocated object.
which suggests
I should probably be storing *pointers* to the class rather than the
class itself? -
If you want to use dynamic memory, yes, you'll have to store pointers
to the 'objects' rather than the 'objects' themselves. But I don't
think you need dynamic memory, certainly not for the example code
below.
but push_back() has signature push_back(const T&) - I'm
confused)
Well the signature is alright if 'T' is 'MyClass*'.

std::vector<int > v;

With this, push_back becomes

push_back(const int &);

and with

std::vector<int *> v;

push_back becomes:

push_back(const int* &);

And a reference to a pointer is like an ordinary pointer (for
simplicity). So whether you have objects or pointers in your vector,
the member functions "adapt" themselves. Actually, that's the essence
of templates.
3). Do I have to manually handle destruction of my objects when:

(a) pop_back is invoked on the vector (in this case what happens to my
last element?)
Again, it depends. The 'object' itself will be destroyed. If the object
is actually a 'pointer', and that pointer points to something you
allocated yourself, you will need to destroy that 'something'.

std::vector<int *> v;

v.push_back(new int(10));

// here, 'v' has a pointer

v.push_back();

// here, 'v' destroyed its pointer, but *not*
// what it pointed at: you just leaked the
// new int

I should have done:

std::vector<int *> v;

v.push_back(new int(10));

// here, 'v' has a pointer

delete v[0];
v.push_back();

// ok!
(b). The vector is resized (who frees my objects at the end?)
WHen a vector is resized, it will never shrink, so that's not a
problem, really.
(c). The vector goes out of scope and its destructor is called?
This is equivalent to a serie of pop_back, so all the discussion above
apply. Again, the vector owns its memory, so it will destroy all the
objects it owns and it will destroy all the memory it owns. If these
objects were pointers, you must destroy the objects they point to
manually.

Here is the code snippet mentioned previously:

#include <vector>
#include <iostream>

using namespace std ;
Not recommended at file scope.
class MyClass {
public:
MyClass(){
cout << "cstor called !" << endl ;
The abbreviation is usually 'ctor'.
i = new int ;
*i = 100 ;
}
Stop.

Your class manages memory. With you have a class which manages memory,
you must remember to rule of three: copy-contructor, assignement
operator and destructor. You have got 1/3, which is 33%. You fail :)

The problem is when you copy a MyClass. Since you have not specified
any copy contructor or assignement operator, the compiler will generate
them. It will copy the pointer (not not the object pointed at).

MyClass m1, m2;
m1 = m2;

Here, m1 and m2 will have their pointer point to the same int in
memory. What's more, you just leaked the int of m1. When m2 will get
out of scope, it will delete its int and then m1 will the delete the
same one. Crash.

"Now I don't make any copies" you say. Well unfortunately, yes, you do.
std::vector, when you insert an object in it, will copy the object. So
std::vector first destroy an object, which deletes an int, and then
your 'mc' object goes out of scope and deletes the same one. Bang.

MyClass(const MyClass &m)
: i(new int(m.i))
{
}

MyClass &operator=(cons t MyClass &m)
{
delete i;
i = new int(m.i);

return this;
} virtual ~MyClass(){
cout << "dstor called !" << endl ;
delete i ;
}

int getVal(void){ return *i ; }
void setVal(int v){ *i=v ;}

private:
int* i ;
};

int main(int argc, char* argv[])
{
MyClass mc ;
std::vector<MyC lass> mv ;

mv.push_back(mc ) ; // Crashes here. Also I want to store
// a dynamic number of objects in the
// vector. How may I do this?
std::vector is *meant* to store a dynamic number of objects. Just call
push_back(), insert(), pop_back(), clear(), erase() or whatever as many
times as you want.
mv.clear ;
This should be

mv.clear();

but is not necessary anyways.
return 0;
}

Jonathan

Jul 23 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
2228
by: Dart | last post by:
This code is okay: class CSingle { public: static CSingle membs; int MEM_NUM; CSingle(int n) { }
1
1266
by: Husam | last post by:
Hi EveryBody: Is there any one know how can I use the following code to make windows application project that can start and stop the windows32 service manually?and tell me what the languege this code is wretin by is it Vb.Net or C# any help will be appreciated CODE: Add a reference to system.management Dim moReturn As Management.ManagementObjectCollection
12
1882
by: questions? | last post by:
I am testing a problem with linked list. I just do a lot of times: create a list, then free it. ############################################# # include <stdio.h> # include <stdlib.h> struct element { int index; struct element *next;
8
1412
by: Thaqalainnaqvi | last post by:
Several times I logged-in successfully but after log-in I can't use features/services which were shown prior to my login. Can anyone exoert from this forum check , is it technical fault of Bank Web Site or this problem pertaining to the user(me). <HTML> <HEAD> <META http-equiv="Content-Type" content="text/html; charset=UTF-8"> <META Http-Equiv="Cache-Control" Content="no-cache">
12
1938
by: JC | last post by:
Hi... Anybody knows what problem has this code? I think, in the Garbage Collector? You know the Solution? The program in the test's case, whit 350 contacts, run OK before number 86. The error is a "Array index out of bounds".
2
1188
by: GaryDean | last post by:
I have inherrited an undocumented asp.net 1.1 application that contains a subproject with about 85 .vb modules that look like they are generated from some kind of data layering tool such as codesmith. I've pasted part of one of the modules below. Does anyone recognize this coding convention? I'm trying to figure out which generator was used so I can go get it to maintain the app. -- Regards, Gary Blakely
1
1203
by: rave3085 | last post by:
Actually this is a part of the code that keeps me wondering why? Dim rsExp As New ADODB.Recordset Dim rsDB As New ADODB.Connection Set rsExp = New ADODB.Recordset Set rsDB = New ADODB.Connection with this i remove ADODB. and wrote it just as a Recordset in all the 4statements above, it worked well.
6
1438
by: MyMarlboro | last post by:
i wish to compare 1 file with multiple files (in a folder) @allfile - >> the paths for all files in a folder but once i run the code below, it keep loop at print "comparing $masterfile with $file1"; if i delete the compare function it works well. what's wrong? Thanks use File::Compare;
1
1204
by: Michelle Chase | last post by:
Option Compare Database 'this one is to use to concatenate the fields Function combine_descriptions() 'turn off warning dialog DoCmd.SetWarnings (False) Dim rst As Recordset Dim strCurrentitemnumber As String
0
8969
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8794
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
9269
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9211
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6756
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6056
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4572
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4826
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2748
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.