Search code examples
c++arraysdata-loss

Array loses data after for loop


I have the following code:

cin >> r >> c;
char map[c][r];
for(int i = 0; i < r; i++)
{
    string line;
    cin >> line;
    for (int j = 0; j < c; ++j) {
        map[j][i] = line[j];
    }
}


int n;
cin >> n;
//cout << "first " << endl << map[0][0] << endl<< map[1][0] << endl<< map[2][0] << endl<< map[3][0] << endl;

pair<pair<int, int>, pair<int,int>> queries[n];
for (int k = 0; k < n; ++k) {
    int r1, c1, r2, c2;
    cin >> r1 >> c1 >> r2 >> c2;
    queries[n] = make_pair(make_pair(r1-1, c1-1), make_pair(r2-1, c2-1));
}
cout << "test" << endl;

I am experiencing a really weird issue, where my map array seems to lose all its data after the second for-loop. I have breakpoints on the lines "int n;" and "cout << "test << endl;"

On the first breakpoint, my char array is filled with the values i expect, but however on the second breakpoint, all the values in the char array is '\000'.

What could be causing this?


Solution

  • Problem one:

    cin >> r >> c;
    char map[c][r];
    

    And later:

    pair<pair<int, int>, pair<int,int>> queries[n];
    

    These are variable length arrays (VLAs) which are a feature of C not C++. VLAs are not part of the C++ language, although many compilers support this an extension. Instead, you can use std::vector<std::vector<char>> to emulate the behavior.

    Problem two:

    for(int i = 0; i < r; i++)
    {
        string line;
        cin >> line;
        for (int j = 0; j < c; ++j) {
            map[j][i] = line[j];
        }
    }
    

    This is undefined behavior since the length of the read string can be smaller than c, but the code accesses c elements regardless of line.length(). It should be:

    for(int i = 0; i < r; i++)
    {
        string line;
        cin >> line;
        for (int j = 0; j < c; ++j) {
            map[j][i] = j < line.length() ? line[j] : '\0';
        }
    }
    

    Problem 3:

    Another undefined behavior

    pair<pair<int, int>, pair<int,int>> queries[n];  // better use std::vector
    for (int k = 0; k < n; ++k) {
       ...
       // Out of bounds queries[n]
       queries[n] = make_pair(make_pair(r1-1, c1-1), make_pair(r2-1, c2-1));
    

    This last one probably trashes your map array. Most likely the out-of-bounds access resides at the same memory location as some of the elements of map.