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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <vector>

using namespace std;

vector<int> 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????

Thanks for your time!

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:
1
2
3
4
5
6
7
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:
1
2
3
4
5
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!"

A little more information might be helpful.
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.