Reputation: 1238
I have encountered this problem and am wondering what its cause is.
My code is as follows:
struct node{
bool leaf;
std::string label;
};
//in main
std::vector<node> graph;
graph.reserve(5);
Now, if i try to assign
graph[3].leaf = true;
,
everything works out.
However, if i try to do the same with an object type, like
graphA[i].label = "01";
,
I get a segmentation fault.
If i change the code to
struct node{
bool leaf;
std::string * label;
};
And allocate the memory for the string in every instance of node
in the vector, I can now assign a value to graphA[i]->label
without a problem.
Why is this? Any responses will be appreciated.
Upvotes: 2
Views: 116
Reputation: 27538
Now, if i try to assign
graph[3].leaf = true;
, everything works out.
It's important to stress that this is a mere coincidence. Nothing works out - you have undefined behaviour because you access graph[3]
when graph
is empty. It would be much better if the program crashed right away, so that you notice something is wrong.
graph
is empty because you confused std::vector
's reserve
and resize
member functions. You don't set the vector's element count to 5, you just ask it to prepare its internally held memory for at least 5 elements in the future. std::vector
is even allowed to ignore this request.
When you do graphA[i].label = "01";
, you also have undefined behaviour, of course.
So why do the first version and the pointer "fix" (which also invokes undefined behaviour) seem to work fine while the other one crashes? C++ as a programming language does not distinguish between different kinds of undefined behaviour. Anything can happen; you may as well experience situations in which the first crashes and the second one "works out". Such is the nature of undefined behaviour.
What probably happens here in practice is that in the bool
and std::string*
case, you are coincidentally writing to a memory location your program is allowed to write to, because you are just dealing with a single bool
or with a single pointer. In the std::string
version, with all of std::string
's automatic dynamic memory management happening behind the scenes, more places in memory are involved and so it happens that you hit a forbidden one.
But that's just a very speculative theory. If you really want to know for sure, debug the code and step into each individual operation. But remember that undefined behaviour is always undefined behaviour.
Upvotes: 1
Reputation: 42858
Now, if i try to assign
graph[3].leaf = true;
You're invoking undefined behavior.
graph
has no element at index 3. In fact, it has no elements at all. You only reserve
d memory for the vector, but didn't add any elements to it.
You can add 5 default-constructed elements using resize
:
graph.resize(5);
Upvotes: 5