   std::vector reserve with POD
  Since std::vector reserve() is required to set capacity() to at least the size passed into reserve(), is it fair to access the memory as an array of POD?  E.g.std::vector<double> v;...v.reserve(1000);v[500] = 10.5;I've been reading mixed things about this, but most make no distinction between POD and other data.  It seems to me like POD would be safe to use, since the memory has been allocated and does not need to be 'constructed'.I would really appreciate some insight into this.  It is more of an intellectual query ... so I am not interested in 'best practice' type responses.  Just whether or not the standard allows it...Thanks!   
  Whether the data is plain or complex makes no difference.The default constructors for additionally created objects will be called.Same thing said another way: std::vector ensures that all of its contents (any index below std::vector.size()) are valid objects (to the extent that the objects themselves behave correctly).*I originally misread the function you were calling, but what I said remains valid.I thought you were calling resize(), not reserve().But as I said, reserve() does not increase size(), thus you may not access indices in the way you are.  If you are accessing below size(), you are accessing a valid object.  It is that simple.Why, in this case, would you use reserve() instead of resize()?L. Spiro   ;  Use resize for that, not reserve. Changing the capacity does not indicate allocation happening. Allocation can be deferred until the first insertion.   ;  AFAIK, reserve is only a hint to the implementation that you'd like to pre-allocate some space -- capacity doesn't necessarily change. So if you were going to try this, I'd at least put assert( v.capacity() >= 1000 ) after the call to reserve so you know when your code breaks.[/edit]But the other replies say, I agree this sounds like a bad idea. In particular, this line:v[500] = 10.5;is likely to trigger an assertion, because operator[] has a precondition that the index passed in is less than size.If you were going to actually try and use this hack, you'd probably have to write:std::vector<double> v(1);v.reserve(1000);double* p = &v[0];//size is 1, this is safep[500] = 10.5;...but as far as I can tell, there's no benefit in doing this rather than just using resize.[Edited by - Hodgman on April 19, 2010 8:33:35 PM];Quote:Original post by HodgmanAFAIK, reserve is only a hint to the implementation that you'd like to pre-allocate some space -- capacity doesn't necessarily change. So if you were going to try this, I'd at least put assert( v.capacity() >= 1000 ) after the call to reserve so you know when your code breaks.Capacity is changed, per 23.2.4.2 - 2 under the following circumstances:Quote:After reserve(), capacity() is greater or equal to the argument of reserve if reallocation happens; and equal to the previous value of capacity() otherwise.Also known as: "It changes when the capacity changes!" rule [grin].   ;Quote:Original post by Hodgman...but as far as I can tell, there's no benefit in doing this rather than just using resize.resize() will zero out the new elements in the vector. reserve() won't. I still wouldn't do it, but there is a minor benefit for the performance conscious.   ;  Okay, resize() it is -- but I am still confused.  If reserve() is increasing capacity, why is the space not accessible?  I understand that resize() will actually call the default constructor, but why does it matter for POD?Basically, I am just trying to get a piece of code to run as fast as possible for giggles and reserve() is running considerably faster than resize() is for my needs.  As far as I know, operator[] does not do an out of bounds check like at(), so I thought that even though size() was still 0, I could access the memory because it had been allocated.  Then again, playing with things under the hood of a class you don't really understand is one of those things you really shouldn't do...   ;Quote:Original post by choffsteinOkay, resize() it is -- but I am still confused.  If reserve() is increasing capacity, why is the space not accessible?  I understand that resize() will actually call the default constructor, but why does it matter for POD?reserve doesn't increase the capacity. It provides a hint to the vector that you expect to insert "at least" that many elements into the it. That MAY involve the vector increasing its capacity, it may not.Quote:Basically, I am just trying to get a piece of code to run as fast as possible for giggles and reserve() is running considerably faster than resize() is for my needs.  As far as I know, operator[] does not do an out of bounds check like at(), so I thought that even though size() was still 0, I could access the memory because it had been allocated.  Then again, playing with things under the hood of a class you don't really understand is one of those things you really shouldn't do...Doing something just because it "works right now!" even though you know it is wrong is A Bad ThingTM. Reserve does not provide any guarantees about when the allocation will happen, or even if it will happen.   ;Quote:Original post by choffsteinAs far as I know, operator[] does not do an out of bounds checkAny implementation worth it's salt will do a bounds check in debug builds for obvious reasons.   ;  Just think of it has having 2 counters: One indicates how many actual objects there are in the list and the other indicates how many objects there could be in the list before it has to increase the size of the list.When adding objects, vectors allocate “ahead” so that the next object you add does not require a whole new allocation, which involves copying objects etc.In other words, if you start with a blank vector and add 1 object to it, it allocates enough space for 32 (just as an example) objects but only constructs/creates the one object you created.  size() will be 1 after this.You add a new object.  It has enough space for that object already, so it does not need to allocate any new RAM.  It constructs the 1 new object and size() is now 2.  It can handle 30 more objects before it needs to change the size of its buffer.Once you add 32 objects, size will be 32.  When you add one more, it does not have enough space to hold that object, so it reallocates the whole list (usually by doubling its allocation size), giving it enough space to hold 64 total objects.  The 32 objects you already created are copied to the newly allocated space and the originals are destroyed.  The new object you were trying to add in the first place is then added to the new buffer after all the others, and size() is now 33.As you can see, when the vector needs to change its allocation size in order to accept more objects, there is a significant amount of overhead.This is why its allocation capacity is not the same as its actual object count.[] operators check bounds on debug builds on nearly all compilers, but do not on release builds.  As I mentioned before, any [] index below size() is valid.  And only those indices.L. Spiro   