### Strange crash

¡Hi!

I come from another forum whith the next problem, very strange, that nobody has been able to explain...

Of course, there are alternatives, but what i want is to understand why that code causes a runtime error.

Here is the code:
 ``123456789101112131415161718192021222324252627282930`` ``````#include #include using namespace std; vector fe; int llegeix() { char c; cin >> c; if (c == '0') return -1; int k = fe.size(); fe.push_back(42); //int aux = llegeix(); fe[k] = llegeix(); //fe[k] = aux; return k; } int main() { llegeix(); for (int i = 0; i < fe.size(); ++i) cout << fe[i] << endl; return 0; }``````

If I try to show the values after de fe[k] = llegeix() assignment (cout << fe[k]), I see that the fisrt values of the vector are 42.

I'm using g++ (MinGW), i have not tried to use other compiler, so i don't know if it is a general problem or if it only is a g++ trouble.

What is happening????

PS: If I uncomment the two commented lines in the llegeix funtion, and i comment the fe[k] = llegeix() I find that there is not any runtime error...

Like cire has said, i have not well explained the problem. Here is an explanation:

The recursive function llegeix, reads characters from the inpunt untill 0 (zero) is introduced, and it returns the fe vector's size when the function was called. In each call it is suposed to store fe.size() + 1 in the vector's fe.size() position.

If I do the next there is not problem:
 ``1234567`` ``````int k = fe.size(); fe.push_back(a_value); int aux = llegeix(); fe[k] = aux;``````

But if I directly assign the function's return value to the vector's last position, the program crashes. That is:
 ``12345`` ``````int k = fe.size(); fe.push_back(a_value); fe[k] = llegeix();``````

this code makes the program to crash. The values stored in the vectro are not correct values. The function executes, returns and when i try to acces the vector's values it crashes.

I have checked the vector's size after the call to the recursive funcion, and it is ok, but trying to acces it's members causes the program to crash.

I don't understand why it happens. Can some one explain it?

¡Thanks!
Last edited on
"Here is my code that I get an error for. It requires input, but I'm not going to tell you what input I used when the error was caused. Not only that, I'm not going to tell you what the error was!"

XD

You have reason.

It doesn't mater what input I use. The function recursively reads characters from the input untill I introduce 0 (zero). But like I have said, the crash have no relation with the input. If I assign the return value of the recursive call to an auxiliar variable, and I assign the value of that variable to the vector's last position, there is not any crash, but if I directly assign the function's return value to the vector's last position, the program crashes.
 It doesn't mater what input I use. The function recursively reads characters from the input untill I introduce 0 (zero).

http://ideone.com/YbwFEO

My gut feeling is that the compiler is caching the location of f[k] as an optimization but it has changed due to reallocation of the internal array for f during the recursive llegix calls.

Perhaps an assembly listing would shed some light.
^ so, `unspecified order of evaluation' leading to UB
sounds reasonable.

By the way, the not obfuscated version `fe.push_back( llegeix() );` should work
edit: nope, backwards
Last edited on
Does seem to be a compiler optimization issue. Works fine compiled with clang++:
 ./gnu.out 1 2 3 4 5 0 42 42 42 42 -1 \$ ./clang.out 1 2 3 4 5 0 1 2 3 4 -1
> Does seem to be a compiler optimization issue.

It is an order of evaluation issue, governed by the sequenced-before rules of C++11. It is a matter of chance that the evaluation orders adopted by g++ and clang++ happen to be different.

`fe[k]` is a function call, as is `llegeix()`; the two are indeterminately sequenced. That is, their evaluations can't overlap, but either may be evaluated before the other.

If `fe[k]` is evaluated first, and `llegeix()` is evaluated later, there would be a problem when the vector needs increase its capacity, to relocate its contents in memory.
@JLBorges

Thanks for the explanation. That was a poor choice of words on my part about something I know very little to nothing about.
Last edited on
ne555 wrote:
^ so, `unspecified order of evaluation' leading to UB

Yes. For some reason the fact that operator[] is just another function for a class type escaped me momentarily, even though I was flirting with the issue.
I would never have guessed that that was the problem. It is too farfetched.

¡Thank you very much for your help!
Topic archived. No new replies allowed.