开发者

Error while accessing dynamically allocated array between classes

UPDATE: Most of my relevant source code is in this pastebin: http://pastebin.com/nhAx1jfG

Can anyone make sense of this error? I'm trying to access a 2d "Tile" array I declare in a different class in the same namespace, it's public, and I do declare an object in the main "rouge.cpp" class.

g++ -Wall -Werror -lncurses -c rouge.cpp -o rouge.o
rouge.cpp: In function ‘void update_game(Player, Map, World, bool)’:
rouge.cpp:497: error: no match for ‘operator[]’ in ‘*(world.World::tiles + ((((unsigned int)player.Player::<anonymous>.GameObject::x) + 0xffffffffffffffffffffffffffffffffu) * 16u))[player.Player::<anonymous>.GameObject::y]’
rouge.cpp:506: error: no match for ‘operator[]’ in ‘*(world.World::tiles + ((((unsigned int)player.Player::<anonymous>.GameObject::x) + 1u) * 16u))[player.Player::<anonymous>.GameObject::y]’
rouge.cpp:515: error: no match for ‘operator[]’ in ‘*(world.World::tiles + ((unsigned int)(((unsigned int)player.Player::<anonymous>.GameObject::x) * 16u)))[(player.Player::<anonymous>.GameObject::y + -0x00000000000000001)]’
rouge.cpp:524: error: no match for ‘operator[]’ in ‘*(world.World::tiles + ((unsigned int)(((unsigned int)player.Player::<anonymous>.GameObject::x) * 16u)))[(player.Player::<anonymous>.GameObject::y + 1)]’
rouge.cpp:540: error: no match for ‘operator[]’ in ‘*(world.World::tiles + ((unsigned int)(((unsigned int)player.Player::<anonymous>.GameObject::x) * 16u)))[player.Player::<anonymous>.GameObject::y]’
make: *** [rouge.o] Error 1

world.h:

// The "world" class, generates a world.
class World
{
    // Public classes and variables
    public:
        // Tile array
        Tile* tiles;
        int plates[WORLDSIZEX][WORLDSIZEY];
        //Tile tiles[WORLDSIZEX][WORLDSIZEY];
        //Tile (*tiles)[WORLDSIZEX] = new Tile[WORLDSIZEX][WORLDSIZEY];
        // For plates
        //int plates[WORLDSIZEX][WORLDSIZEY];
        //plates = new int[WORLDSIZEX][WORLDSIZEY];
        //int (*plates)[WORLDSIZEX] = new int[WORLDSIZEX][WORLDSIZEY];
        // Small world
        Tile smalltiles[SMALLWORLDX][SMALLWORLDY];
        // For world temp
        int worldtemp;
        // Constructor
        World();
        void generate_plates();
        bool check_plates();
        int build_mountains(int,int);
        void add_mountains();
        void generate_world();
        void shrink_world();
        void save_world();
        void erupt();
        bool get_passable(int,int);
        char get_icon(int,int);
        char get_small_icon(int,int);
        int get_color(int,int);
        int get_small_color(int,int);
};

world.cpp where I allocate the array:

// Constructor
World::World()
{
    // Seed for random numbe开发者_如何转开发r
    srand( time(NULL) );
    tiles = new Tile[WORLDSIZEX][WORLDSIZEY];
    // Generate a world
    generate_world();
    // Shrink world
    shrink_world();
    // Then save it.
    //save_world();
}

in rouge.cpp, I access it just like:

world.tiles[i][j]; //i and j are ints in a nested for loop

after I declare it like:

World world;

and it's spitting out that error


You're using a pointer to point to an array that was dynamically allocated as a multidimensional array. After the address of this multidimensional array is stored in World::tiles, the compiler "forgets" that the array was multidimensional. Thus, you can no longer use the double brackets notation (tiles[x][y]) to access an element.

To get around this, you have at least 4 options:

  1. Provide a method in World that takes x,y coordinates and returns a reference to the desired cell (you might want to provide both const and non-const versions):

    Tile& at(size_t x, size_t y) {return tiles[y*WORLDSIZEX + x];}

    const Tile& at(size_t x, size_t y) const {return tiles[y*WORLDSIZEX + x];}

  2. Roll-up your own 2D array class for World::tiles.

  3. Use a boost::multi_array for World::tiles.

  4. Declare World::tiles as vector< vector<Tile> >. The initial sizing of all nested vectors is tricky, but after that you can use the world.tiles[x][y] notation.

Plus the option @fsmc gave you.


I took a quick look at your code in the pastebin. It would be much more efficient (and cleaner looking) if you initialized your tiles vectors like this instead:

tiles.resize(WORLDSIZEX);
for(int i = 0; i < WORLDSIZEX; i++)
{
    tiles[i].resize(WORLDSIZEY);
}


world.tiles is of type Tile*. It is the wrong type to be a two dimensional array (you would need Tile**, and need to initialize it in two steps (one to create an array of Tile* pointers, and a loop to create an array that each of those Tile * pointers can point to.

e.g. in your class def:

Tile **tiles

e.g.: in your constructor:

tiles = new Tile*[SMALLWORLDX];
for (int i = 0; i < SMALLWORLDX; i++)
   tiles[i] = new Tile[SMALLWORLDY];

So getting back to what was causing your original error- when you were calling world.tiles[x][y], the first [] operator was okay, because tiles could be pointing to an array of Tiles, but the second one is not okay.


Just based on the error message, whatever you are trying to index is not actually an array. The '*' (dereference) operator at the beginning of that statement looks suspicious to me, but without actually seeing your code I can't say much else.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜