views:

72

answers:

4

Consider the following public method that adds an integer variable to a vector of ints(private member) in a class in C++.

KoolMethod()
{
  int x;
  x = 10;
  KoolList.Add(x);
}
Vector<int>KoolList;

But is this a valid addition to a vector ??? Upon calling the method, it creates a local variable. The scope of this local variable ends the moment the execution control leaves the method. And since this local variable is allocated on a stack(on the method call), any member of KoolList points to an invalid memory location in deallocated stack which may or may not contain the expected value of x. Is this an accurate description of above mechanism ??

Is there a need for creating an int in heap storage using "new" operator everytime a value needs to be added to the vector like described below ????:

KoolMethod()
{
  int *x = new int();
  *x = 10;
  KoolList.Add(x);
}
 Vector<int*>KoolList;   
+2  A: 

But is this a valid addition to a vector?

Yes, a (standard library) vector stores copies.

Is there a need for creating an int in heap storage using "new" operator

If you don't want the objects to be copied or to work with polymorphic objects (see object slicing) you'd use pointers. In that case you should preferably avoid dealing with deallocation manually and use wrappers (smart pointers or pointer containers) though to get exception safety back.

Georg Fritzsche
When is the second case with integer pointers valid or appropriate ??
de costo
@de costo: See the update.
Georg Fritzsche
A: 

If you create a vector of ints, it will not be a vector of pointers. The integers are stored by value, no pointers involved, and therefore you won't run into any problems with invalid memory addresses.

Here's an example of code that would cause such a problem:

std::vector<int *> my_list;

void a_method() {
    int value = 2; // allocated on the stack
    my_list.push_back(&value); // pushes a pointer to the stack... not good
}
Matti Virkkunen
+2  A: 

A Vector<int> (at least if it is std::vector) stores elements by value, so calls to add() creates a copy of the parameter object and stores that copy into the array. Therefore it doesn't matter what happens with the original object, the copy within the vector is alive as long as the vector itself (unless removed or overwritten explicitly, of course).

A Vector<X*> may be more appropriate if you

  • want to work with polymorphic X objects,
  • don't want to copy objects of X e.g. because it's expensive or disallowed,
  • want to share the same objects between different parties.

Of course, none of these applies to int, only to real objects. Still, it is better to store smart pointers in the vector instead of raw pointers, e.g. vector<auto_ptr<X> > or vector<shared_ptr<X> >. These automatically manage the disposal of objects for you.

Péter Török
["Why is it wrong to use std::auto_ptr<> with STL containers?"](http://stackoverflow.com/questions/111478/why-is-it-wrong-to-use-stdauto-ptr-with-stl-containers)
Georg Fritzsche
@Georg, oops, my bad. Thanks for pointing it out :-)
Péter Török
A: 

Think about this: adding to the standard vector creates copy of added object.

In the first code snippet, you use vector of ints, so you'll add the copy of local int and everything is fine.

In the second code snippet you use vector of pointers to int, so you'll add the copy of a pointer (not the copy of the object this pointer is pointing to). Since the object pointed by the pointer will be still valid after leaving the method (it's initialized using new operator and it's not deleted anywhere) everything will be fine too.

chalup