Question

I've been pretty confused while programming before, but this one takes the cake. Basically I set the value in one for loop, and in the following iteration it changes to the value of the next one.

for (int i = 0; i < 2; ++i)
{
    for (int j = 0; j < numWords[i]; ++j) //numWords [0] = 9, numWords [1] = 7
    {
        stb[i][j].word = const_cast<char*>(is (j + 1,1).c_str()); //is(int,length[opt]) converts int to string, c_str() returns const char *, but I need char *
        cout << is(j+1,1) << ' ' << stb[i][j].word << '\n';
    }
}

for (int i = 0; i < 2; ++i)
{
    for (int j = 0; j < numWords [i]; ++j)
    {
        cout << stb[i][j].word << ' ';
    }
    cout << '\n';
}

Output:

1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
1 1
2 2 
3 3
4 4
5 5 
6 6
7 7 
7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7

My only guess now is something with the const, but it doesn't make sense why it would keep changing all previous array elements...

Was it helpful?

Solution

This is pretty simple. Your program has undefined behaviour (if my assumptions about is() are correct).

is(int, length) returns a std::string by value. You get a pointer to some internal structure in that string by using c_str(). This string is then destructed at the end of the full-expression. This destruction invalidates the pointers that you obtained from c_str().

This means that you fill up the array with pointers to invalid memory. You then read from these pointers to print out the contents of the array. Reading from invalid memory results in undefined behaviour.

A possible explanation for the observed behaviour is this:

Each string that is returns reuses the same memory. In the first loop you read from the memory before it has been overwritten by another call to is, and so you get the correct value. In the second loop you read from the memory after it has been overritten, and so you get the final value in the array.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top