segmentation fault...

F

Fei Liu

What's wrong with the following code? It seems I can't assign to a
vector<string> element...

#include <vector>
#include <iostream>
#include <iterator>
#include <functional>
#include <string>

using namespace std;

struct c{
vector<string> a;
void set_size(int n) { a.reserve(n); }
void set_val(int i, string v) { a = v; }
};

void foo(c & cc){
cc.set_size(10);
cc.set_val(3, "value 3");
}

int main(){

vector<int> a;
a.reserve(10);
a[3] = 10;
copy(a.begin(), a.end(), ostream_iterator<int>(cout, " "));
cout << "a[3]: " << a[3] << endl;
{
vector<string> a;
a.reserve(10);
a[3] = "value 3";
copy(a.begin(), a.end(), ostream_iterator<string>(cout, " "));
cout << "a[3]: " << a[3] << endl;
}

c cc;
foo(cc);
}
 
J

Jerry Coffin

[email protected] says... said:
int main(){

vector<int> a;
a.reserve(10);
a[3] = 10;

This gives undefined behavior. a.reserve(10) only _reserves_ space for
10 elements, but does NOT actually add those 10 elements to the vector.
This ensures that you can add 10 elements to 'a' without a reallocation
taking place, so (for example) all iterators into 'a' remain valid
until/unless you add an eleventh element. It does NOT, however, make it
valid to index into those 10 elements until you add them (e.g. with
push_back).

If you change the 'reserve' to 'resize', this part of the code will
become valid -- resize actually adds elements to the vector, so you can
then index into the vector and use those elements.

[ ... ]
vector<string> a;
a.reserve(10);
a[3] = "value 3";

This has the same problem, which can be fixed in the same way (i.e.
change 'reserve' to 'resize').
 
V

Victor Bazarov

Fei said:
What's wrong with the following code? It seems I can't assign to a
vector<string> element...
[..]

RTFM about the differences between 'reserve' and 'resize'.

V
 
R

Robert Bauck Hamar

Fei said:
What's wrong with the following code? It seems I can't assign to a
vector<string> element...

You have no elements to assign to. I believe you don't understand what
reserve() actually does, it does not create any elements, it only reserves
space for them. Try using a.at(i) instead of a.

What you really want is the resize() member function of vector.
#include <vector>
#include <iostream>
#include <iterator>
#include <functional>
#include <string>

#include said:
using namespace std;

struct c{
vector<string> a;
void set_size(int n) { a.reserve(n); }
void set_val(int i, string v) { a = v; }
};

void foo(c & cc){
cc.set_size(10);
cc.set_val(3, "value 3");
}

int main(){

vector<int> a;
a.reserve(10);


a.size() == 0
a[3] = 10;

Undefined behaviour. Use
a.at(3) = 10;
copy(a.begin(), a.end(), ostream_iterator<int>(cout, " "));

OK. a.begin() == a.end()
cout << "a[3]: " << a[3] << endl;
UB.

{
vector<string> a;
a.reserve(10);

a.size() == 0
a[3] = "value 3";

Undefined behaviour. While the previous errors are also undefined behaviour,
i guess this is what actually _caused_ the crash? A likely reason is that
a[3] returns some raw memory, on which no string has been constructed.
copy(a.begin(), a.end(), ostream_iterator<string>(cout, " "));

again, a.begin() == a.end(), so this is a no-op.
cout << "a[3]: " << a[3] << endl;

But this is UB again.
}

c cc;
foo(cc);

And UB.
 
F

Fei Liu

Jerry said:
[email protected] says... said:
int main(){

vector<int> a;
a.reserve(10);
a[3] = 10;

This gives undefined behavior. a.reserve(10) only _reserves_ space for
10 elements, but does NOT actually add those 10 elements to the vector.
This ensures that you can add 10 elements to 'a' without a reallocation
taking place, so (for example) all iterators into 'a' remain valid
until/unless you add an eleventh element. It does NOT, however, make it
valid to index into those 10 elements until you add them (e.g. with
push_back).

If you change the 'reserve' to 'resize', this part of the code will
become valid -- resize actually adds elements to the vector, so you can
then index into the vector and use those elements.

[ ... ]
vector<string> a;
a.reserve(10);
a[3] = "value 3";

This has the same problem, which can be fixed in the same way (i.e.
change 'reserve' to 'resize').

Thank you!
 

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
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top