Why does the [] operator in vector behave as it does?

Luke Dickens lwd03@doc.ic.ac.uk
Wed Apr 30 14:55:00 GMT 2008


Hi,

I am using the  g++ (GCC) 4.1.3 version of the compiler, which I have 
installed under ubuntu gutsy, and compile from my eclipse cdt IDE.

I have started a c++ project in which I wish to use the vector template 
to store objects (say class A) which contain pointers to other objects 
on the heap, and I occasionally want to replace entries in my vector. So 
I want my old entry to be destroyed, and a new entry to be added. 
Moreover, I read access this object referenced by index much more often 
and hence prefer the vector over a map, for instance.

I have tried to explain with a short pseudo-code example, please see 
attached file for a more detailed example of this as a .cpp file.

Example:
Consider I have a vector of n objects of type A, all initialised in some 
way, and a new object type A (called a_new) that I wish to insert in the 
vector at the i_th position (replacing the old contents). So with

unsigned int n = 3, i=1;
vector<A> vec = vector<A>(n,A(0));
A a_new = A(1);

My first thought was to do this to replace things.

vec[i] = a_new;

But  a_new's destructor is called when a_new goes out of scope and this 
is referenced by vec[i], hence vec[i] no longer points to a valid place 
in memory. In other words our A(1) object only exists in this scope.

I know this was stupid, but by these ways do we learn. So next I tried 
creating an object on the heap and referencing this with vec[i]. This 
required a copy constructor for A, but no problem.

vec[i] = *(new A(a_new));

This worked, and what is more when I called vec.clear() this object was 
destroyed. One would assume that I was then happy. But in checking the 
destructor I discovered that the original object at vec[i]  (the A(0) 
object) did not call its own destructor.

Even if this object was destroyed in some other way by the vector, by 
deallocating the memory in some low level way. It doesn't do any of the 
cleaning up I require, since in my case my A objects themselves have 
pointers to the heap, and this indirect memory usage is not being 
deallocated.

Finally, I tried (in desperation)

A* tmp = &(vec[i]);
vec[i] = *(new A(a_new));
delete tmp;

This unsurprisingly called the destructor on tmp, but in the process the 
vec[i] reference became invalid, in other words at the delete command, 
tmp was pointing to the same object as vec[i].

As I said above, I have attached a .cpp file with this behaviour shown 
in more detail. Am I missing something, or is this behaviour somehow not 
correct? If it is correct then shouldn't the [] operator only return a 
'const reference' instead of a reference. I apologise if this is an 
idiotic question.

Luke

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: main.cpp
URL: <https://gcc.gnu.org/pipermail/gcc-help/attachments/20080430/554c5c3a/attachment.ksh>


More information about the Gcc-help mailing list