I need help with class arrays

Started by
2 comments, last by Chris Oden 16 years, 3 months ago
(correct me if I mix up any terms, still learning much of the basics of programming) I'm trying to set up an array of 10*20 classes, the PassiveBlock declaration and definition is in another .h and .cpp file respectively.

    board.x = BOARD_X_OFFSET;
    board.y = BOARD_Y_OFFSET;
    board.w = BOARD_WIDTH;
    board.h = BOARD_HEIGHT;
	
    PassiveBlock *passiveBlocks;

    passiveBlocks = new PassiveBlock[ BOARD_WIDTH ][ BOARD_HEIGHT ];

    for( int X = 0; X < board.w ; X++ )
    {
        for( int Y = 0; Y < board.h; Y++ )
        {
            passiveBlocks[ X ][ Y ].Init( X + board.x, Y + board.y );
        }
    }

I'm using VC++ now, this worked in DevC++, the code is copied from DevC++ and it worked until VC++ registered a change in this part and wanted to recompile. My guess is that VC++ don't like it this way. In my C++ book this should work for arrays with one [] but I'm probably messing it up with multiple []'s. Thanks in advance for any help.
Advertisement
new can only allocate one-dimensional arrays. You will have to handle multiple dimensions yourself.

I would personally suggest either using std::vector twice, or boost::multi_array with two dimensions once.
The correct way to create your two-dimensional dynamic array in C++ is to allocate a one-dimensional array of PassiveBlock pointers, then iterate (loop) over each element of that array and for each one allocate another array of PassiveBlocks.

Generally speaking, two-dimensional arrays aren't always your friend, either use boost::multi_array or use a one-dimensional array and access it like a two-dimensional array:

    passiveBlocks = new PassiveBlock[BOARD_WIDTH * BOARD_HEIGHT];    for( int X = 0; X < board.w ; X++ )    {        for( int Y = 0; Y < board.h; Y++ )        {            passiveBlocks[ Y * BOARD_WIDTH + X ].Init( X + board.x, Y + board.y );        }    }    /*        do stuff    */    delete[] passiveBlocks; // Don't forget this!


You can still do better than that and use std::vector which is recommended instead of using new[]:
    std::vector<PassiveBlock> passiveBlocks( BOARD_WIDTH * BOARD_HEIGHT );    for( int X = 0; X < board.w ; X++ )    {        for( int Y = 0; Y < board.h; Y++ )        {            passiveBlocks[ Y * BOARD_WIDTH + X ].Init( X + board.x, Y + board.y );        }    }

If PassiveBlock is fitted with a constructor that fullfills the same job as the Init method then you could also ditch Init and do it this way:
    std::vector<PassiveBlock> passiveBlocks;    passiveBlocks.reserve( BOARD_WIDTH * BOARD_HEIGHT );    for( int Y = 0; Y < board.h ; Y++ )    {        for( int X = 0; X < board.w; X++ )        {            passiveBlocks.push_back( PassiveBlock(X + board.x, Y + board.y) );        }    }


As your problem partially demonstrates, using new[] and delete[] (especially for multi-dimensional arrays) is error prone, using the correct RAII container for the job is almost always better [smile]

Hope that was of some help.
It's alive!

Yeah, this worked wonders :)

Thanks alot, learned something new.

This topic is closed to new replies.

Advertisement