vector.reserve

J

john smith

HI, when I try the following code, I get a segfault when compiled with
VC.NET and g++ under cygwin.

#1 vector<int> vi;
#2 vector<int>::iterator ii = vi.begin();
#3 vi.reserve(10);
#4 for(int i = 0; i < 10; ++i) {
#5 *ii++ = 4;
#6 }
#7 copy(vi.begin(), vi.end(), ostream_iterator<int>(cout, " "));

Here is my break down on why this code should work (fill a vector with
numbers, nevermind v syntax, or v.push_back(), or the fill(...) stl
function. I really wanted to know why the use of iterators causes a problem
here).

#1 - v.size is 0;
#2 - initiate a interator and point to v.begin().
#3 - make space for 10 more elements, v.size() is still 0;
#4-6 - loop and assign each space in the vector a number. #5 is where segv
happens.

I was under the assumption that reserve will make space available to add
more element, which the iterator will be able to walk through them. I'd
appreciate any help on this issue.

Smith
 
D

Daniel Seitz

Daniel Seitz wrote in message ...
Your iterator is invalid. Obtain it after you call reserve();

Oh, and it's not really "invalid", but vi.begin() == vi.end(). I hope no
confusion came of this. Read 23.1, item 7.
 
Y

yangyong

vector::reserve increment vector capacity,not size.
capacity and size are diff.

MSDN sample.


#include <iostream>
#include <vector>

using namespace std ;

typedef vector<int> INTVECTOR;

void main()
{
// Dynamically allocated vector begins with 0 elements.
INTVECTOR theVector;

// Add one element to the end of the vector, an int with the value 42.
theVector.push_back(42) ;

// Show statistics about vector.
cout << "theVector's size is: " << theVector.size() << endl;
cout << "theVector's maximum size is: " << theVector.max_size()
<< endl;
cout << "theVector's capacity is: " << theVector.capacity() << endl;

// Ensure there's room for at least 1000 elements.
theVector.reserve(1000);
cout << endl << "After reserving storage for 1000 elements:" << endl;
cout << "theVector's size is: " << theVector.size() << endl;
cout << "theVector's maximum size is: " << theVector.max_size()
<< endl;
cout << "theVector's capacity is: " << theVector.capacity() << endl;

// Ensure there's room for at least 2000 elements.
theVector.resize(2000);
cout << endl << "After resizing storage to 2000 elements:" << endl;
cout << "theVector's size is: " << theVector.size() << endl;
cout << "theVector's maximum size is: " << theVector.max_size()
<< endl;
cout << "theVector's capacity is: " << theVector.capacity() << endl;
}


Program Output is:


theVector's size is: 1
theVector's maximum size is: 1073741823
theVector's capacity is: 1

After reserving storage for 1000 elements:
theVector's size is: 1
theVector's maximum size is: 1073741823
theVector's capacity is: 1000

After resizing storage to 2000 elements:
theVector's size is: 2000
theVector's maximum size is: 1073741823
theVector's capacity is: 2000
HI, when I try the following code, I get a segfault when compiled with
VC.NET and g++ under cygwin.

#1 vector<int> vi;
#2 vector<int>::iterator ii = vi.begin();
#3 vi.reserve(10);
#4 for(int i = 0; i < 10; ++i) {
#5 *ii++ = 4;
#6 }
#7 copy(vi.begin(), vi.end(), ostream_iterator<int>(cout, " "));

Here is my break down on why this code should work (fill a vector with
numbers, nevermind v syntax, or v.push_back(), or the fill(...) stl
function. I really wanted to know why the use of iterators causes a problem
here).

#1 - v.size is 0;
#2 - initiate a interator and point to v.begin().
#3 - make space for 10 more elements, v.size() is still 0;
#4-6 - loop and assign each space in the vector a number. #5 is where segv
happens.

I was under the assumption that reserve will make space available to add
more element, which the iterator will be able to walk through them. I'd
appreciate any help on this issue.

Smith
 
J

Jonathan Mcdougall

HI, when I try the following code, I get a segfault when compiled with
VC.NET and g++ under cygwin.

#1 vector<int> vi;

This is an empty vector
#2 vector<int>::iterator ii = vi.begin();

This is a valid iterator, but since the vector is empty, being() and
end() have the same value.
#3 vi.reserve(10);

Two things : 1) These 10 new elements are not valid, _capacity_ and
_size_ are two different beasts. You increase the capacity with
reserve(), but you increase the size with, among others, push_back().

2) you just invalidated your iterator, because the location of the
elements may have changed (and they probably did).
#4 for(int i = 0; i < 10; ++i) {
#5 *ii++ = 4;

Undefined behavior, since the vector is still empty. Your application
may now crash at any time (or send some porn to your girlfriend`s
email address, you never know. C++ is quite polyvalent).
#6 }
#7 copy(vi.begin(), vi.end(), ostream_iterator<int>(cout, " "));

This would have worked if you did not try to dereference your
iterator. Nothing should have been printed on the screen, since the
vector is still empty.
Here is my break down on why this code should work

It should'nt.
(fill a vector with
numbers, nevermind v syntax, or v.push_back(), or the fill(...) stl
function.
what?

I really wanted to know why the use of iterators causes a problem
here).


Because you try to access an empty vector.
#1 - v.size is 0;
ok

#2 - initiate a interator and point to v.begin().
ok

#3 - make space for 10 more elements, v.size() is still 0;

that's it, you have the space for 10 elements, but it is illegal to
access these elements since they are not initialized. The only thing
you have here is raw memory. Do not try to access it.
#4-6 - loop and assign each space in the vector a number. #5 is where segv
happens.
I was under the assumption that reserve will make space available to add
more element, which the iterator will be able to walk through them. I'd
appreciate any help on this issue.

std::vector::reserve() only increases the vector's capacity so that it
will avoid reallocation and it invalidates iterators. What's more,
these new elements are not valid elements, that is, you cannot access
them. The only reason for which you would want to use reserve() is to
avoid reallocation.

Jonathan
 
J

John Harrison

john smith said:
HI, when I try the following code, I get a segfault when compiled with
VC.NET and g++ under cygwin.

#1 vector<int> vi;
#2 vector<int>::iterator ii = vi.begin();
#3 vi.reserve(10);
#4 for(int i = 0; i < 10; ++i) {
#5 *ii++ = 4;
#6 }
#7 copy(vi.begin(), vi.end(), ostream_iterator<int>(cout, " "));

Here is my break down on why this code should work (fill a vector with
numbers, nevermind v syntax, or v.push_back(), or the fill(...) stl
function. I really wanted to know why the use of iterators causes a problem
here).

#1 - v.size is 0;
#2 - initiate a interator and point to v.begin().
#3 - make space for 10 more elements, v.size() is still 0;
#4-6 - loop and assign each space in the vector a number. #5 is where segv
happens.

I was under the assumption that reserve will make space available to add
more element,
Yes.

which the iterator will be able to walk through them.


No. The only way to add elements to a vector is to change its size, for
instance by calling resize, push_back or insert
I'd
appreciate any help on this issue.

Smith

reserve is just something you call for efficiency, it stops repeated
reallocations when you are adding multiple elements by using push_back or
insert. reserve also invalidates any iterators to the vector.

Here's how you should of done it.

vector<int> vi;
vi.resize(10);
copy(vi.begin(), vi.end(), ostream_iterator<int>(cout, " "));

john
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,134
Messages
2,570,780
Members
47,337
Latest member
HenriettaA

Latest Threads

Top