vector push back

I asked earlier about the vector resize, and I think I've got that issue figured out. I'm struggling with the push back now though. I thought it was working out okay, but for some reason it isn't adding the new data like it's supposed to. It's coming up with random numbers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <class T>
void Vector <T> :: push_back (const T & t)
{
   //do we have space?
   if (capacity == 0)
      resize(1);
   else if (numItems == capacity)
      resize(capacity*2);
   assert (numItems < capacity);

   //add the item
   numItems++;
   data[numItems] = t;
}
If the vector is initially empty, then numItems will be 0, capacity will be 0. The vector is resized to 1 (assuming resize() works). capacity will now be 1, numItems will still be 0. assert is OK. numItems is incremented to 1. The memory at location (data + numItems) ie *(data + 1) will be set to t.

What about the memory location at (data + 0) ????

Don't you need to increment numItems after the assignment, rather than before?
If I increment the items after the assignment then it will overwrite the last item currently in the list, right? It needs to add something after the last item on the list. I've also tried

data[numItems++] = t;

but that has the same problem. It's still assigning a random number instead of what it's supposed to be.
okay, I just figured out what you were saying about data + 0, I guess that makes sense. I just tried doing it after, and it's still having the same problem though
Is resize() working as expected? Use the debugger to trace through the code (including resize) to see where is the issue.
12
13
numItems++;
data[numItems] = t;

You probably are going out of bounds with your internal container. That is likely why you are getting garbage values, what you call random numbers.

Try swapping lines 12 & 13. Increment the number of elements AFTER you store the new value at the end.
okay, I've changed it to increment after, but it didn't really change anything. My resizer appears to be working correctly, as far as I can tell. If I do it once, it shows that it resizes from 0 to 1, then if I do it again, it resizes from 1 to 2. The third time I do it though, it tells me that it successfully resized from 2 to 4, but then it crashes when it tries to add the data, every time.
What does your resize actually do? Is it the same as jonnin's code from your previous post which doesn't change numItems?

Note that for std::vector, there is resize() and reserve(). reserve() just increases capacity but doesn't change the number of items in the vector. resize() changes the number of items and increases capacity as needed.

For your push_back to operate the way of std::vector, I would have expected it to call reserve() instead of resize().

Where is numItems set to 0? In the constructor?

It's coming up with random numbers.


How do you know? Have you code to display the vector? Is the problem with this code? Is it showing addresses rather than content?

Post you whole vector code so we can see the interactions.

PS Use the debugger.

Last edited on
resize(capacity*2);

i'd assume if capacity ==0 then you resize to 1. if its 1 you multiply by 2 which is 2. if its 2x2 then thats 4....
unsigned int capacity;
resize (pow(2, capacity)); // 0 is 1, 1 is 2, 2 is 4, 3 is 8, ...
or just check it, if they put in 0, error out

you have to get a clear pic in your mind...
you have a thing, and it has X usable locations.
Y locations are actually used. if x==y, next time you try to add one, you need to reallocate/resize it.
so you have to track its actual size, its used size, and keep them straight in your head. If you mix up the two ideas you will have problems.
Last edited on
The third time I [resize] though, it tells me that it successfully resized from 2 to 4, but then it crashes when it tries to add the data, every time.
That's a pretty good indication that your resize() function is actually not working properly. Please your entire code.
Topic archived. No new replies allowed.