Error with multidimensional vector

I am having trouble accessing a one-dimensional vector as a multi-dimensional one.
I have a MultiArray template class, and it is accessed using the function operator. It accesses elements through the expression row * m_columns + col. The row and col are the two inputs to the operator while the m_columns is the width/number of columns in the array. There is also a version that accesses the array with one number. Its underlying representation is a one-dimensional vector.

The problem is when I try to load a level:
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
void Map::LoadFromFile(const std::string& filename)
    {
        std::ifstream map_file(filename);

        std::cout << m_map.GetHeight() << ", " << m_map.GetWidth() << std::endl;
        std::cout <<  m_map_dimensions.y << ", " <<  m_map_dimensions.x << std::endl;
        if(map_file.is_open())
        {
            for(unsigned int i = 0; i < m_map_dimensions.y; i++)
            {
                for(unsigned int j = 0; j < m_map_dimensions.x; j++)
                {
                    int current_tile;
                    map_file >> current_tile;

                    try
                    {
                            m_map(i, j) = current_tile;
                    }
                    catch(std::exception& e)
                    {
                        std::cerr << "Vector overflow in map loading." << std::endl;
                        exit(EXIT_FAILURE);
                    }
                }
            }
        }
        else
            std::cerr << "Couldn't load map file: " << filename << "." << std::endl;
    }

(The m_map is a MultiArray<int> and the m_map_dimensions an sf::Vector2u)

The dimensions of the level are 20 * 15 (screen dimensions divided by height dimensions), so I made a map file that looks like this:
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


but it loads it skewed and only ever accesses up to element 229 in the MultiArray.

This is how it loads the file:
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
I'd be easier if your map was a one dimensional vector and you had 2 intergers stating the map width and height. Just sayin'
Last edited on by Fredbill30
Fredbill30 wrote:
I'd be easier if your map was a one dimensional vector and you had 2 intergers stating the map width and height. Just sayin'

If you can't be bothered to read the post, don't respond to it. Just sayin'.

@OP:

You don't have a sanity check on the input extraction to see if the input stream remains valid or enters an error state within your loops, but it's hard to say what may be going wrong with only the snippet you've posted.


I overlooked the post, sorry.
I've done some testing and it seems to be filling the 16th through 20th slots with the 1st through 5th slots of the next row. If I output the value of a tile right after it is set, then it will show the correct values. But anytime I access it afterwards, it is skewed as I described. Here is my revised 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
31
32
33
34
35
36
void Map::LoadFromFile(const std::string& filename)
    {
        std::ifstream map_file(filename);

        std::cout << "Size of m_map: " << m_map.size() << std::endl;
        std::cout << "Dimensions of m_map: " << m_map.GetHeight() << ", " << m_map.GetWidth() << std::endl;
        std::cout << "Dimensions of map vector: " << m_map_dimensions.x << ", " <<  m_map_dimensions.y << std::endl;
        if(map_file.is_open())
        {
            int current_tile;
            for(unsigned int i = 0; i < m_map_dimensions.y; i++)
            {
                for(unsigned int j = 0; j < m_map_dimensions.x; j++)
                {
                    if(map_file >> current_tile)
                    {
                        try
                        {
                            m_map(i, j) = current_tile;
                            std::cout << m_map(i, j) << " ";
                        }
                        catch(std::exception& e)
                        {
                            std::cerr << "Vector overflow in map loading. Error: " << e.what() << std::endl;
                        }
                    }
                    else
                        std::cerr << "Error getting tile from map." << std::endl;
                }
                std::cout << std::endl;
            }
            std::cout << std::endl;
        }
        else
            std::cerr << "Couldn't load map file: " << filename << "." << std::endl;
    }


And my overloaded operators for my MultiArray:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
T& operator() (unsigned int row, unsigned int col)
{
#ifdef DEBUGBUILD
#ifdef DOUTPUT
std::cout << "Accessing element " << row * m_columns + col << "in multimap" << std::endl;
#endif // DOUTPUT
#endif // DEBUGBUILD
return m_data.at(row * m_columns + col);
}
T const& operator() (unsigned int row, unsigned int col) const
{
#ifdef DEBUGBUILD
#ifdef DOUTPUT
std::cout << "Accessing element " << row * m_columns + col << "in multimap" << std::endl;
#endif // DOUTPUT
#endif // DEBUGBUILD
return m_data.at(row * m_columns + col);
}
Topic archived. No new replies allowed.