Jump to content
  • Advertisement
Sign in to follow this  
Cacks

C++ 2D arrays

This topic is 4837 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys, got a problem creating a 2D array in C++. I want to declare a pointer to the 2D array in my header, then when initializing an object allocate the memory for it. I want to do something like this: //Header bool spaces[][]; //.cpp file spaces = new bool[width][height]; OR Maybe //Header bool* spaces; //.cpp file spaces = new bool[width][height]; ?? This seems like it should be easy, what am I doing wrong? Thanks for any help!

Share this post


Link to post
Share on other sites
Advertisement
My program won't compile & gives the following errors;

1. non-constant expression as array bound

2. error C2440: '=' : cannot convert from 'bool (*)[1]' to 'bool * '
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style
cast or function-style cast

Share this post


Link to post
Share on other sites
This is a complicated thing but this is how you do it:



bool (* spaces)[10];

spaces = new bool[10][10];




ace

Share this post


Link to post
Share on other sites
They are both ints

For example, the following lines;

int* arr = new int[12]; - Is OKAY
int* arr = new int[12][12]; - NOT OKAY

Any ideas?

Share this post


Link to post
Share on other sites
There is no operator new[][] in C++ - it is limited to 1D arrays.

There are a couple ways to go about what you're attempting in C++. First, the ugly way, is to create a 1D array of pointers to 1D arrays (or in ace_lovegrove's example, a 1D array of 1D arrays of fixed size) like so:

//allocation:
int ** foo;
foo = new int * [width];
for ( int x = 0 ; x < width ; ++x ) {
foo[x] = new int[ height ];
}

//use:
foo[x][y] = 13;

//deallocation:
for ( int x = 0 ; x < width ; ++x ) {
delete[] foo[x];
}
delete[] foo;




One could convert the above example to something easier to clean up by using std::vector, of course, like so:
#include <vector>

std::vector< std::vector< int > > foo;
for ( foo int x = 0 ; x < width ; ++x ) {
foo[x].resize( height );
}

//use:
foo[x][y] = 13;

//deallocation is automatic when foo goes out of scope




Finally, there's boost::multi_array, a fine part of the Boost C++ Libraries:
#include <boost/multi_array.hpp>

//allocation:
boost::multi_array< int , 2 > foo( boost::extents[width][height] ); //2 = two dimentions

//use:
foo[x][y] = 13;

//deallocation is automatic when foo goes out of scope




Out of these three examples, I'd suggest the last. The boost library collection has many excellent tools, and it is well worth installing.

Share this post


Link to post
Share on other sites
Only the outermost array dimension can be left unspecified.

In other words, while an array a[row][col] can have as many rows as you want, you must tell the compiler how many columns it has, otherwise it cannot compute the offset necessary to go from one line to the next.

So in your case bool spaces[][height] is the best you can get, short of manually allocating an array of arrays.

Save yourself some trouble, use a std::vector with manual 2D-indexing index = row*rowsize + col or go use boost::multi_array.

edit: What MaulingMonkey said.

Share this post


Link to post
Share on other sites
You can only dynamically allocate one dimension at a time. You have three options:

  1. Allocate the first dimension as a sequence of pointers, then allocate the second dimension to each pointer. This has interesting memory characteristics and pointer arithmetic semantics.
    int ** arr2d = new int * [length];
    for (int n = 0; n < length; ++n)
    arr2d[n] = new int [height];

    You have to deallocate in reverse order:
    for (int n = 0; n < length; ++n)
    delete [] arr2d[n];
    delete [] arr2d;

  2. Allocate the entire block linearly, then use either pointer arithmetic or other skullduggery to simulate native 2D semantics.
    int index2d(int x, int y)
    {
    return y * height + x;
    }

    ...

    int * real_arr2d = new int [length * height];
    real_arr2d[index2d(1, 1)] = 5;

  3. Use nested std::vector.

    vector< vector<int> > arr2d;
    arr2d.reserve(length);
    for (int n = 0; n < length; ++n)
    {
    vector<int> v(height)
    arr2d.push_back(v);
    }


[Edit: whoops! Forgot std::vector...]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!