469,929 Members | 1,443 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,929 developers. It's quick & easy.

std::vector: reserve required?

In std::vector, is reserve or resize required?

On:
Linux mbrc32 2.6.22.1-41.fc7 #1 SMP Fri
Jul 27 18:10:34 EDT 2007 i686 athlon
i386 GNU/Linux
Using:
g++ (GCC) 4.1.2 20070502 (Red Hat 4.1.2-12)

The program below fails, but if the reserve(en)
is uncommented, it works. Is this as expected?

// vectst.cc 07/04/08

#include <iostream>
#include <vector>
using namespace std;

int main(int argc, const char* argv[])
{
int en = 10;
vector<int vec;

// vec.reserve(en);
for (int jj = 0; jj < en; ++jj)
vec[jj] = jj;
for (int jj = 0; jj < en; ++jj)
cout << vec[jj] << endl;

exit (0);
}

Thanks,
Mike.
Jul 4 '08 #1
23 3080

Mike -- Email Ignored wrote:
In std::vector, is reserve or resize required?

On:
Linux mbrc32 2.6.22.1-41.fc7 #1 SMP Fri
Jul 27 18:10:34 EDT 2007 i686 athlon
i386 GNU/Linux
Using:
g++ (GCC) 4.1.2 20070502 (Red Hat 4.1.2-12)

The program below fails, but if the reserve(en)
is uncommented, it works. Is this as expected?

// vectst.cc 07/04/08

#include <iostream>
#include <vector>
using namespace std;

int main(int argc, const char* argv[])
{
int en = 10;
vector<int vec;

// vec.reserve(en);
for (int jj = 0; jj < en; ++jj)
vec[jj] = jj;
for (int jj = 0; jj < en; ++jj)
cout << vec[jj] << endl;

exit (0);
}

Thanks,
Mike.

No, you could do that (use reserve), or, use push_back()

int main(int argc, const char* argv[])
{
int en = 10;
vector<int vec;

for (int jj = 0; jj < en; ++jj)
vec.push_back(jj);
for (int jj = 0; jj < en; ++jj)
cout << vec[jj] << endl;

return 0;
}
Jul 4 '08 #2
Mike -- Email Ignored wrote:
In std::vector, is reserve or resize required?
No, but you need to fill the vector somehow. You can do that either upon
construction, or by using push_back, insert, or resize.

The reserve() method, on the other hand does not grow the vector.
>
On:
Linux mbrc32 2.6.22.1-41.fc7 #1 SMP Fri
Jul 27 18:10:34 EDT 2007 i686 athlon
i386 GNU/Linux
Using:
g++ (GCC) 4.1.2 20070502 (Red Hat 4.1.2-12)

The program below fails, but if the reserve(en)
is uncommented, it works.
It does not. You are observing a manifestation of undefined behavior.
Is this as expected?
There are no expectations as to how undefined behavior will show itself.

From a quality of implementation point of view, would want to see an abort
if you compile the program with assertions turned on.

// vectst.cc 07/04/08

#include <iostream>
#include <vector>
using namespace std;

int main(int argc, const char* argv[])
{
int en = 10;
vector<int vec;

// vec.reserve(en);
for (int jj = 0; jj < en; ++jj)
vec[jj] = jj;
for (int jj = 0; jj < en; ++jj)
cout << vec[jj] << endl;
Try something like

cout << vec.size() << endl;

and ponder the meaning of what you get.
>
exit (0);
}

Best

Kai-Uwe Bux
Jul 4 '08 #3
On Jul 4, 7:44*am, Darío Griffo <dario.griffo.lis...@gmail.comwrote:
Mike -- Email Ignored wrote:
In std::vector, is reserve or resize required?
On:
* *Linux mbrc32 2.6.22.1-41.fc7 #1 SMP Fri
* * * Jul 27 18:10:34 EDT 2007 i686 athlon
* * * i386 GNU/Linux
Using:
* *g++ (GCC) 4.1.2 20070502 (Red Hat 4.1.2-12)
The program below fails, but if the reserve(en)
is uncommented, it works. *Is this as expected?
// vectst.cc 07/04/08
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, const char* argv[])
{
* *int * * * * * * * * *en = 10;
* *vector<int* * * * *vec;
// * vec.reserve(en);
* *for (int jj = 0; jj < en; ++jj)
* * * vec[jj] = jj;
* *for (int jj = 0; jj < en; ++jj)
* * * cout << vec[jj] << endl;
* *exit (0);
}
Thanks,
Mike.

No, you could do that (use reserve), or, use push_back()
reserve() does not make the vector larger. You must have meant "you
could use resize or push_back."

Ali
Jul 4 '08 #5
On Jul 4, 7:54*am, callumurquh...@googlemail.com wrote:
http://www.cplusplus.com/reference/stl/vector/operator[].html
If the OP did not concentrate on the vec.reserve(en), the document you
show could be used to help with the problem. But because the OP does
expect some behavior from vec.reserve(en), the problem is not with
operator[].

Ali
Jul 4 '08 #6
On Fri, 04 Jul 2008 08:30:37 -0700, acehreli wrote:
On Jul 4, 7:54Â*am, callumurquh...@googlemail.com wrote:
>http://www.cplusplus.com/reference/stl/vector/operator[].html

If the OP did not concentrate on the vec.reserve(en), the document you
show could be used to help with the problem. But because the OP does
expect some behavior from vec.reserve(en), the problem is not with
operator[].

Ali
Another test using:
vec.reserve(en);
for (int jj = 0; jj < en; ++jj)
vec[jj] = jj;
cout << "vec.size() = " << vec.size() << endl;

prevents the crash, but vec.size() returns zero, showing that
in this case, reserve() really does not work.

Mike.
Jul 4 '08 #7

acehr...@gmail.com wrote:
reserve() does not make the vector larger. You must have meant "you
could use resize or push_back."

Ali
Yes, you're right
Jul 4 '08 #8
LR
Mike -- Email Ignored wrote:
On Fri, 04 Jul 2008 08:30:37 -0700, acehreli wrote:
>On Jul 4, 7:54 am, callumurquh...@googlemail.com wrote:
>>http://www.cplusplus.com/reference/stl/vector/operator[].html
If the OP did not concentrate on the vec.reserve(en), the document you
show could be used to help with the problem. But because the OP does
expect some behavior from vec.reserve(en), the problem is not with
operator[].

Ali

Another test using:
vec.reserve(en);
for (int jj = 0; jj < en; ++jj)
vec[jj] = jj;
cout << "vec.size() = " << vec.size() << endl;

prevents the crash, but vec.size() returns zero,
What does vec.capacity() return?
showing that
in this case, reserve() really does not work.
I think it doesn't do what you expect. But why do you think it doesn't work?

Please consider this:
#include <iostream>
#include <vector>

int main() {
const unsigned int en = 10;
std::vector<intv;
//
std::cout << "a " << v.size() << " " << v.capacity() << std::endl;
v.reserve(en);
std::cout << "b " << v.size() << " " << v.capacity() << std::endl;
//
for(unsigned int i=0; i<en; i++) {
v[i] = i;
}
//
v.push_back(-8);
std::cout << "c " << v.size() << " " << v.capacity() << std::endl;
//
for(unsigned int i=0; i<en; i++) {
std::cout << "[" << i << "] " << v[i] << std::endl;
}
}
Also, please consider this:
#include <iostream>
#include <vector>

int main() {
const unsigned int en = 10;
std::vector<intv;
std::cout << "a " << v.size() << " " << v.capacity() << std::endl;
v.resize(en); // there's more than one way to do it
std::cout << "b " << v.size() << " " << v.capacity() << std::endl;
//
v[0] = -8;
v[9] = -7;
v.push_back(-9);
std::cout << "c " << v.size() << " " << v.capacity() << std::endl;
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout,
" "));
}
LR
Jul 4 '08 #9
Mike -- Email Ignored wrote:
On Fri, 04 Jul 2008 08:30:37 -0700, acehreli wrote:
>On Jul 4, 7:54 am, callumurquh...@googlemail.com wrote:
>>http://www.cplusplus.com/reference/stl/vector/operator[].html
If the OP did not concentrate on the vec.reserve(en), the document you
show could be used to help with the problem. But because the OP does
expect some behavior from vec.reserve(en), the problem is not with
operator[].

Ali

Another test using:
vec.reserve(en);
for (int jj = 0; jj < en; ++jj)
vec[jj] = jj;
cout << "vec.size() = " << vec.size() << endl;

prevents the crash, but vec.size() returns zero, showing that
in this case, reserve() really does not work.
No, reserve() does work. You misunderstand how it does.
vector<>::reserve changes the CAPACITY -- that is, you can use
push_back() or resize() up to the amount you've reserved without
the vector reallocating. It does not change the SIZE of the vector.

Try this:

#include <iostream>
#include <ostream>
#include <vector>

using namespace std;

int main()
{
vector<intv;

cout << "size = " << v.size() << "\n"
<< "capacity = " << v.capacity << "\n";

v.reserve(200);

cout << "size = " << v.size() << "\n"
<< "capacity = " << v.capacity << "\n";

v.resize(200);

cout << "size = " << v.size() << "\n"
<< "capacity = " << v.capacity << endl;

return 0;
}
Jul 4 '08 #10
red floyd wrote:
Mike -- Email Ignored wrote:
>On Fri, 04 Jul 2008 08:30:37 -0700, acehreli wrote:
>>On Jul 4, 7:54 am, callumurquh...@googlemail.com wrote:
http://www.cplusplus.com/reference/stl/vector/operator[].html
If the OP did not concentrate on the vec.reserve(en), the document you
show could be used to help with the problem. But because the OP does
expect some behavior from vec.reserve(en), the problem is not with
operator[].

Ali

Another test using:
vec.reserve(en);
for (int jj = 0; jj < en; ++jj)
vec[jj] = jj;
cout << "vec.size() = " << vec.size() << endl;

prevents the crash, but vec.size() returns zero, showing that
in this case, reserve() really does not work.

No, reserve() does work. You misunderstand how it does.
vector<>::reserve changes the CAPACITY -- that is, you can use
push_back() or resize() up to the amount you've reserved without
the vector reallocating. It does not change the SIZE of the vector.

Try this:

#include <iostream>
#include <ostream>
#include <vector>

using namespace std;

int main()
{
vector<intv;

cout << "size = " << v.size() << "\n"
<< "capacity = " << v.capacity << "\n";

v.reserve(200);

cout << "size = " << v.size() << "\n"
<< "capacity = " << v.capacity << "\n";

v.resize(200);

cout << "size = " << v.size() << "\n"
<< "capacity = " << v.capacity << endl;

return 0;
}
Crap. Typo. All those v.capacity calls should be v.capacity()
Jul 4 '08 #11
On Jul 4, 4:50 pm, Kai-Uwe Bux <jkherci...@gmx.netwrote:
Mike -- Email Ignored wrote:
On:
Linux mbrc32 2.6.22.1-41.fc7 #1 SMP Fri
Jul 27 18:10:34 EDT 2007 i686 athlon
i386 GNU/Linux
Using:
g++ (GCC) 4.1.2 20070502 (Red Hat 4.1.2-12)
The program below fails, but if the reserve(en) is
uncommented, it works.
I get a core dump from g++ 4.2.1, when I compile with the usual
options. With or without the reserve() commented out. You
probably forgot the necessary options to make g++ usable. (One
of these days, someone will come out with a compiler which is
usable without special options. But it's not happened yet.)
It does not. You are observing a manifestation of undefined
behavior.
Is this as expected?
There are no expectations as to how undefined behavior will
show itself.
Yes and no. From experience, I find that undefined behavior
usually works in all of your tests, and then fails in the most
embarassing way possible in the demo before the most important
client.
From a quality of implementation point of view, would want to
see an abort if you compile the program with assertions turned
on.
You do with g++. I'm pretty sure you also do with VC++, but I
don't have a Windows machine handy here to test it with.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jul 4 '08 #12
On Fri, 04 Jul 2008 13:13:43 -0700, James Kanze wrote:
On Jul 4, 4:50 pm, Kai-Uwe Bux <jkherci...@gmx.netwrote:
>Mike -- Email Ignored wrote:
On:
Linux mbrc32 2.6.22.1-41.fc7 #1 SMP Fri
Jul 27 18:10:34 EDT 2007 i686 athlon
i386 GNU/Linux
Using:
g++ (GCC) 4.1.2 20070502 (Red Hat 4.1.2-12)
The program below fails, but if the reserve(en) is uncommented, it
works.

I get a core dump from g++ 4.2.1, when I compile with the usual options.
With or without the reserve() commented out. You probably forgot the
necessary options to make g++ usable. (One of these days, someone will
come out with a compiler which is usable without special options. But
it's not happened yet.)
You may have forgotten some option if you get a failure with reserve()
uncommented; in my case options are correct as verified by extensive
use in other contexts.
>
>It does not. You are observing a manifestation of undefined behavior.
Is this as expected?
>There are no expectations as to how undefined behavior will show
itself.

Yes and no. From experience, I find that undefined behavior usually
works in all of your tests, and then fails in the most embarassing way
possible in the demo before the most important client.
I guess I should have said I was referring to the standard as is
usually the case on this group. There is no "Yes and no".
>From a quality of implementation point of view, would want to see an
abort if you compile the program with assertions turned on.

You do with g++. I'm pretty sure you also do with VC++, but I don't
have a Windows machine handy here to test it with.
I see that in you use vec.at(jj) instead of vec[jj], it throws
an exception if the index is out of range. I changed the code to use
vec.at(jj) where there is uncertainly. My problem is solved.

Mike.
Jul 4 '08 #13
On Fri, 04 Jul 2008 20:25:40 +0000, Mike -- Email Ignored wrote:
On Fri, 04 Jul 2008 13:13:43 -0700, James Kanze wrote:
[...]
>I get a core dump from g++ 4.2.1, when I compile with the usual
options.
With or without the reserve() commented out. You probably forgot the
necessary options to make g++ usable. (One of these days, someone will
come out with a compiler which is usable without special options. But
it's not happened yet.)

You may have forgotten some option if you get a failure with reserve()
uncommented; in my case options are correct as verified by extensive use
in other contexts.
Correction. You may have no option error. As indicated elsewhere
in this thread, reserve() is never correct in the original code
presented. Hopefully, if you use resize() instead, the code will work.

[...]

Mike.

Jul 4 '08 #14
On Jul 4, 10:25 pm, Mike -- Email Ignored <m_d_berger_1...@yahoo.com>
wrote:
On Fri, 04 Jul 2008 13:13:43 -0700, James Kanze wrote:
On Jul 4, 4:50 pm, Kai-Uwe Bux <jkherci...@gmx.netwrote:
Mike -- Email Ignored wrote:
On:
Linux mbrc32 2.6.22.1-41.fc7 #1 SMP Fri
Jul 27 18:10:34 EDT 2007 i686 athlon
i386 GNU/Linux
Using:
g++ (GCC) 4.1.2 20070502 (Red Hat 4.1.2-12)
The program below fails, but if the reserve(en) is
uncommented, it works.
I get a core dump from g++ 4.2.1, when I compile with the
usual options. With or without the reserve() commented out.
You probably forgot the necessary options to make g++
usable. (One of these days, someone will come out with a
compiler which is usable without special options. But it's
not happened yet.)
You may have forgotten some option if you get a failure with
reserve() uncommented; in my case options are correct as
verified by extensive use in other contexts.
I used the usual options that I use for compiling production
code:
-std=c++98
-ffor-scope
-fno-gnu-keywords
-foperator-names
-pipe
-Wall
-W
-Wno-sign-compare
-Wno-deprecated
-Wno-non-virtual-dtor
-Wpointer-arith
-Wno-unused
-Wno-switch
-Wno-missing-field-initializers
-ggdb3
-D_GLIBCXX_CONCEPT_CHECKS
-D_GLIBCXX_DEBUG
-D_GLIBCXX_DEBUG_PEDANTIC
They're not complete (I forget why we don't have -pedantic in
there), but they're a start.

The important ones for error checking in the library are the
last three. Logically, they should be the default, but hey, no
compiler I know gets the defaults right.
It does not. You are observing a manifestation of undefined
behavior.
Is this as expected?
There are no expectations as to how undefined behavior will
show itself.
Yes and no. From experience, I find that undefined behavior
usually works in all of your tests, and then fails in the
most embarassing way possible in the demo before the most
important client.
I guess I should have said I was referring to the standard as is
usually the case on this group. There is no "Yes and no".
I guess I should have explained in detail that this was meant as
a somewhat humorous characterization. It didn't occur to me
that anyone would miss this.
From a quality of implementation point of view, would want
to see an abort if you compile the program with assertions
turned on.
You do with g++. I'm pretty sure you also do with VC++, but
I don't have a Windows machine handy here to test it with.
I see that in you use vec.at(jj) instead of vec[jj], it throws
an exception if the index is out of range. I changed the code
to use vec.at(jj) where there is uncertainly. My problem is
solved.
Except that you want an abort, not an exception. (The problem
isn't cases where there is uncertainly. Uncertainty can be
removed by means of an if. The problem is where your certitudes
turn out to be wrong.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jul 5 '08 #15
On Jul 4, 10:35 pm, Mike -- Email Ignored <m_d_berger_1...@yahoo.com>
wrote:
On Fri, 04 Jul 2008 20:25:40 +0000, Mike -- Email Ignored wrote:
On Fri, 04 Jul 2008 13:13:43 -0700, James Kanze wrote:
[...]
I get a core dump from g++ 4.2.1, when I compile with the
usual options.
With or without the reserve() commented out. You probably forgot the
necessary options to make g++ usable. (One of these days, someone will
come out with a compiler which is usable without special options. But
it's not happened yet.)
You may have forgotten some option if you get a failure with reserve()
uncommented; in my case options are correct as verified by extensive use
in other contexts.
Correction. You may have no option error. As indicated elsewhere
in this thread, reserve() is never correct in the original code
presented. Hopefully, if you use resize() instead, the code will work.
Obviously, because it's then correct. (There are doubtlessly
some bugs still floating around somewhere in the GNU library,
but nothing that obvious.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jul 5 '08 #16
On Sat, 05 Jul 2008 00:08:49 -0700, James Kanze wrote:
On Jul 4, 10:25 pm, Mike -- Email Ignored <m_d_berger_1...@yahoo.com>
wrote:
[...]
>
I used the usual options that I use for compiling production code:
-std=c++98
-ffor-scope
-fno-gnu-keywords
-foperator-names
-pipe
-Wall
-W
-Wno-sign-compare
-Wno-deprecated
-Wno-non-virtual-dtor
-Wpointer-arith
-Wno-unused
-Wno-switch
-Wno-missing-field-initializers
-ggdb3
-D_GLIBCXX_CONCEPT_CHECKS
-D_GLIBCXX_DEBUG
-D_GLIBCXX_DEBUG_PEDANTIC
They're not complete (I forget why we don't have -pedantic in there),
but they're a start.
You use many more options than I do. Are all these really necessary?

[...]
Except that you want an abort, not an exception. (The problem isn't
cases where there is uncertainly. Uncertainty can be removed by means
of an if. The problem is where your certitudes turn out to be wrong.)
Why an abort rather than an exception? I would think that it
depend on the application.

For certitude, consider things like:

std::vector<int vec;
...
for (int jj = 0; jj < vec.size(); ++jj)
cout << vec[jj] << endl;

I first went through the code and changed all [] to at. Then I
looked back and saw things like the above fragment, and decided
I was being ridiculous, and throwing away cycles for nothing.

Mike.

Jul 5 '08 #17
In article <91Lbk.990$bn3.816@trnddc07>, m_*************@yahoo.com
says...

[ ... ]
For certitude, consider things like:

std::vector<int vec;
...
for (int jj = 0; jj < vec.size(); ++jj)
cout << vec[jj] << endl;

I first went through the code and changed all [] to at. Then I
looked back and saw things like the above fragment, and decided
I was being ridiculous, and throwing away cycles for nothing.
Better still, replace the whole loop with:

std::copy(vec.begin(), vec.end(),
std::ostream_iterator<int>(std::cout, "\n"));

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 5 '08 #18
"Mike -- Email Ignored" <m_*************@yahoo.comwrote in message
news:cBqbk.257$9W.47@trndny04...
In std::vector, is reserve or resize required?

On:
Linux mbrc32 2.6.22.1-41.fc7 #1 SMP Fri
Jul 27 18:10:34 EDT 2007 i686 athlon
i386 GNU/Linux
Using:
g++ (GCC) 4.1.2 20070502 (Red Hat 4.1.2-12)

The program below fails, but if the reserve(en)
is uncommented, it works. Is this as expected?
No. It is unspecified behavior either way. reserve will allocate memory to
extend the size of an array, but it does not actually grow the size.
resize() will both allocate the memory and extend the size also.

Note, that changing vec[jj] = jj;
to vec.push_back( jj );
would mean you don't need resize or reserve. However, if you know before
hand how much memory you are going to need, how many elements, you may wish
to resize it to avoid needless calls to new.

int en = 10;
vec<intvec;

vec.reserve( en ); // Allocates memory, doesn't change size
for (int jj = 0; jj < en; ++jj)
vec.push_back( jj );

alternately:
vec.resize( en ); // Allocates memory and changes size
for (int jj = 0; jj < en; ++jj)
vec[jj] = jj;

// vectst.cc 07/04/08

#include <iostream>
#include <vector>
using namespace std;

int main(int argc, const char* argv[])
{
int en = 10;
vector<int vec;

// vec.reserve(en);
for (int jj = 0; jj < en; ++jj)
vec[jj] = jj;
for (int jj = 0; jj < en; ++jj)
cout << vec[jj] << endl;

exit (0);
}

Jul 5 '08 #19
On Jul 5, 3:53 pm, Mike -- Email Ignored <m_d_berger_1...@yahoo.com>
wrote:
On Sat, 05 Jul 2008 00:08:49 -0700, James Kanze wrote:
On Jul 4, 10:25 pm, Mike -- Email Ignored <m_d_berger_1...@yahoo.com>
wrote:
[...]
I used the usual options that I use for compiling production code:
-std=c++98
-ffor-scope
-fno-gnu-keywords
-foperator-names
-pipe
-Wall
-W
-Wno-sign-compare
-Wno-deprecated
-Wno-non-virtual-dtor
-Wpointer-arith
-Wno-unused
-Wno-switch
-Wno-missing-field-initializers
-ggdb3
-D_GLIBCXX_CONCEPT_CHECKS
-D_GLIBCXX_DEBUG
-D_GLIBCXX_DEBUG_PEDANTIC
They're not complete (I forget why we don't have -pedantic in there),
but they're a start.
You use many more options than I do. Are all these really necessary?
They were at one time, in the context I was working. Options
are a lot like includes: you add them when you need them, but
they don't get removed if the cease to be necessary:-). Also,
-pedantic is generally recommended, but I don't have it. I do
remember having it once, but I forget why I removed it. (I
think it was because -pedantic turned off support for long long,
which I need, even if it isn't currently part of C++. But I
also seem to recall having seen recently that there is a
separate option which can be used to control this, overriding
-pedantic.)

Typically, however, I'd say that that list is about average for
what you need with just about any compiler.
[...]
Except that you want an abort, not an exception. (The
problem isn't cases where there is uncertainly. Uncertainty
can be removed by means of an if. The problem is where your
certitudes turn out to be wrong.)
Why an abort rather than an exception? I would think that it
depend on the application.
It's a programming error. Something which can't happen, but
did. In such cases, you can no longer make any assumptions
concerning the state of the program, and the best thing you can
do is to terminate as quickly as possible, executing as little
code as possible.

And yes, it does depend on the application. That's a more or
less general rule, which leans toward safety and robustness; in
some cases, however, if an error goes unnoticed, it's not an
error, and whether it's noticed immediately or an undeterminate
moment downstream doesn't matter. (A typical case might be
games programming.)
For certitude, consider things like:

std::vector<int vec;
...
for (int jj = 0; jj < vec.size(); ++jj)
cout << vec[jj] << endl;
I first went through the code and changed all [] to at. Then
I looked back and saw things like the above fragment, and
decided I was being ridiculous, and throwing away cycles for
nothing.
What cycles are you throwing away. In one case, the library
code verifies the index, and then aborts, and in the other, it
verifies the index, and then raises an exception. In a well
written library, with normal options, you execute the if, and
nothing else, in either version. (And of course, a good
compiler can, and probably should, recognize that the if can
never fail, and suppress it.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jul 5 '08 #20
James Kanze wrote:
On Jul 4, 4:50 pm, Kai-Uwe Bux <jkherci...@gmx.netwrote:
>Mike -- Email Ignored wrote:
>>On:
Linux mbrc32 2.6.22.1-41.fc7 #1 SMP Fri
Jul 27 18:10:34 EDT 2007 i686 athlon
i386 GNU/Linux
Using:
g++ (GCC) 4.1.2 20070502 (Red Hat 4.1.2-12)
>>The program below fails, but if the reserve(en) is
uncommented, it works.

I get a core dump from g++ 4.2.1, when I compile with the usual
options. With or without the reserve() commented out. You
probably forgot the necessary options to make g++ usable. (One
of these days, someone will come out with a compiler which is
usable without special options. But it's not happened yet.)
Might be OT, but What options are you using for g++?

>It does not. You are observing a manifestation of undefined
behavior.
>>Is this as expected?
>There are no expectations as to how undefined behavior will
show itself.

Yes and no. From experience, I find that undefined behavior
usually works in all of your tests, and then fails in the most
embarassing way possible in the demo before the most important
client.
"Whatever can go wrong will go wrong, and at the worst possible time, in
the worst possible way"
Jul 7 '08 #21
In article <2n***********@newsfe02.lga>,
Jim Langston <ta*******@rocketmail.comwrote:
>No. It is unspecified behavior either way. reserve will allocate memory to
extend the size of an array, but it does not actually grow the size.
resize() will both allocate the memory and extend the size also.

Note, that changing vec[jj] = jj;
to vec.push_back( jj );
would mean you don't need resize or reserve. However, if you know before
hand how much memory you are going to need, how many elements, you may wish
to resize it to avoid needless calls to new.
Hmm, I would frown on the gratuitous use of resize()
>int en = 10;
vec<intvec;

vec.reserve( en ); // Allocates memory, doesn't change size
for (int jj = 0; jj < en; ++jj)
vec.push_back( jj );
OK but more important if en is large.
>alternately:
vec.resize( en ); // Allocates memory and changes size
// And initialise all elements !
>for (int jj = 0; jj < en; ++jj)
vec[jj] = jj;
Yes, you do avoid reallocating of the vector buffer however,
vec.resize() will default initialize all elements in the vector. This
is likely to be much more expensive than using reserve() or even what
you would have to pay for using push_back() directly without
pre-reserving anything.

The typical use of resize would be more:

// some C API that returns data:
// void c_foo( int * buffer , size_t bufferSize )

//C++ code:

std::vector<intv;
v.resize(200);
// get data using the C API:
c_foo( &v[0], v.size() );
// now you can use the data in the vector

Yannick
Jul 9 '08 #22

"Yannick Tremblay" <yt******@nyx.nyx.netwrote in message
news:12***************@irys.nyx.net...
In article <2n***********@newsfe02.lga>,
Jim Langston <ta*******@rocketmail.comwrote:
>>No. It is unspecified behavior either way. reserve will allocate memory
to
extend the size of an array, but it does not actually grow the size.
resize() will both allocate the memory and extend the size also.

Note, that changing vec[jj] = jj;
to vec.push_back( jj );
would mean you don't need resize or reserve. However, if you know before
hand how much memory you are going to need, how many elements, you may
wish
to resize it to avoid needless calls to new.

Hmm, I would frown on the gratuitous use of resize()
Yes, resize should only be used (in this code) if the vec[jj] syntax or
using the buffer directly. Using push_back() .reserve() should suffice.
>>int en = 10;
vec<intvec;

vec.reserve( en ); // Allocates memory, doesn't change size
for (int jj = 0; jj < en; ++jj)
vec.push_back( jj );

OK but more important if en is large.
Yes and no, since "large" is an abstract value. The simple addition of
..reserve() can save quite a number of new's and copies, enough that using it
if you know the size can make a big difference, and I don't know of any case
where it would actually hurt. Since en here is a non constant variable we
can figure that the programmer doesn't know what size it will actually be
here but will be set on some arbitary information. And since the program
knows at this point how big the vector will need to be, we might possibly
save a lot of needless news and copies by using reserve.

Usually, in my cases anyway, when using vectors I don't know before hand how
big the vector is going to be and just let it grow as needed.

Premature optimization? Hard to say. It depends on how often this code is
going to be called, etc.. but, really, if you know somehow how big the
vector is going to be, why not tell the vector?
>>alternately:
vec.resize( en ); // Allocates memory and changes size
// And initialise all elements !
>>for (int jj = 0; jj < en; ++jj)
vec[jj] = jj;

Yes, you do avoid reallocating of the vector buffer however,
vec.resize() will default initialize all elements in the vector. This
is likely to be much more expensive than using reserve() or even what
you would have to pay for using push_back() directly without
pre-reserving anything.

The typical use of resize would be more:

// some C API that returns data:
// void c_foo( int * buffer , size_t bufferSize )

//C++ code:

std::vector<intv;
v.resize(200);
// get data using the C API:
c_foo( &v[0], v.size() );
// now you can use the data in the vector
Personally, I get uncomfortable using vec[jj] = ... syntax without knowing
that the elements were already in the vector. Which is where resize would
come in with using this syntax. In my own programs I would use the first
version, the .reserve() and push_back(), but it's a matter of choice I
think.

I pretty much agree with all your comments, other that I would use
..reserve() any time I knew before hand how big the vector was going to be.
Jul 9 '08 #23
On Jul 9, 3:35 pm, ytrem...@nyx.nyx.net (Yannick Tremblay) wrote:
In article <2nQbk.13$w...@newsfe02.lga>,
Jim Langston <tazmas...@rocketmail.comwrote:
No. It is unspecified behavior either way. reserve will
allocate memory to extend the size of an array, but it does
not actually grow the size. resize() will both allocate the
memory and extend the size also.
Note, that changing vec[jj] = jj;
to vec.push_back( jj );
would mean you don't need resize or reserve. However, if you
know before hand how much memory you are going to need, how
many elements, you may wish to resize it to avoid needless
calls to new.
Hmm, I would frown on the gratuitous use of resize()
If you're going to use [] on the elements afterwards, it's not
gratuitous:-).
int en = 10;
vec<intvec;
vec.reserve( en ); // Allocates memory, doesn't change size
for (int jj = 0; jj < en; ++jj)
vec.push_back( jj );
OK but more important if en is large.
For a sufficient definition of large. In practice, I've never
really found it to make a measurable difference. But then, I
don't construct vectors with millions of elements which are
expensive to copy. Which brings up the second point: it's more
important if the elements are expensive to copy.
alternately:
vec.resize( en ); // Allocates memory and changes size
// And initialise all elements !
for (int jj = 0; jj < en; ++jj)
vec[jj] = jj;
Yes, you do avoid reallocating of the vector buffer however,
vec.resize() will default initialize all elements in the
vector. This is likely to be much more expensive than using
reserve() or even what you would have to pay for using
push_back() directly without pre-reserving anything.
That's what I would have thought, too. Measurements with
vector<intand vector<double>, on the other hand, show the
resize version to be considerably faster. On a Sparc, at least:
I just reran a benchmark, and found the version with resize
faster on Sparc, but the version with push_back and reserve
faster on a PC under Linux (both compiled with g++, using the
same options: -std=c++98 -pedantic -ffor-scope -fno-gnu-keywords
-foperator-names -pipe -Wall -W -Wno-sign-compare
-Wno-deprecated -Wno-non-virtual-dtor -Wpointer-arith
-Wno-unused -Wno-switch -Wno-missing-braces -Wno-long-long
-static-libgcc -O3 -fomit-frame-pointer -finline-functions

I'd still use push_back in this case; it seems more idiomatic.
And at the first sign of a performance problem, I'd slip in a
reserve (although I certainly wouldn't bother with it until
there was a performance problem).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jul 10 '08 #24

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

10 posts views Thread by Stefan Höhne | last post: by
4 posts views Thread by enzo | last post: by
18 posts views Thread by Janina Kramer | last post: by
11 posts views Thread by Steve | last post: by
8 posts views Thread by Alex Vinokur | last post: by
8 posts views Thread by Ross A. Finlayson | last post: by
7 posts views Thread by Dilip | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.