4

salute..

I am learning dynamic allocations for multidimensional arrays in a book and I found some ways for that, And now haven't problem in it. But the author of the book shows us a way, but it doesn't work correctly. It is this:

pbeans = new double [3][4];         // Allocate memory for a 3x4 array

And this is the error:

error C2440: '=' : cannot convert from 'int (*)[4]' to 'int *'

how should i define pbeans ( if this type of coding is legal)?

and what is the problem exactly?

Regards.

C77431
  • 99
  • 3
  • 8
  • You might find [C++ Faqs](http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.16) (and the FAQs immediately following it) helpful to understanding this. By the way, this is a good thing to know about, but in general you should just use container classes (e.g., the standard template library). And if you do use `new`, you'll usually want to wrap it in a container class or at least use a smart pointer. Tenfour's code looks more complicated than Alnitak's because it is more production-ready; it protects you from memory leaks via [RAII](http://en.wikipedia.org/wiki/RAII) – Brian Feb 20 '11 at 15:57

3 Answers3

3

This is covered in my FAQ on arrays:

double (*pbeans)[4];
pbeans = new double[3][4];

// ...

delete[] pbeans;

For the "C declarator impaired", you could make that more readable with a typedef:

typedef double row[4];

row *pbeans;
pbeans = new row[3];

// ...

delete[] pbeans;

But in C++, we prefer RAII containers over raw pointers:

#include <vector>
#include <array>

std::vector<std::array<double, 4> > beans(3);

Note the complete absence of delete[] which makes this solution exception-safe.

Community
  • 1
  • 1
fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • I prefer this method because it also makes it very clear what your dimensions represent. – tenfour Feb 20 '11 at 16:16
  • 1
    @C77: Note that the original error message already hinted at the type required for pbeans: `int (*)[4]`. It's just that many programmers don't have a clue what that funny combination of tokens could possibly mean. Curse you, C declarator syntax! – fredoverflow Feb 20 '11 at 16:20
  • If the values are static then there is no new for new/delete. If both are dynamic you need to deallocate each row separately see p2DArray example here: http://www.cplusplus.com/forum/articles/7459/ – Nux Jul 25 '13 at 11:49
1

You need to allocate each dimension of the array separately:

double **pbeans = new double*[3];
for (int i = 0; i < 3; ++i) {
    pbeans[i] = new double[4];
}
Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • Thanks, So that is illegal and should i put the book in recycle bin? (: – C77431 Feb 20 '11 at 15:30
  • well you _can_ just say `double pbeans[3][4]`, but that'll create the variable on the stack and not the heap. – Alnitak Feb 20 '11 at 15:35
  • 1
    Actually, you *can* create multidimensional arrays dynamically without allocating each dimension separately. See my answer. – fredoverflow Feb 20 '11 at 16:03
0

Here is a way to do it that allocates the memory contiguously on the heap:

typedef double MyGrid[3][4];

int main(int argc, char* argv[])
{
    MyGrid& x = *(reinterpret_cast<Grid*>(new double[12]));
    ...
    x[1][2] = 0.3333;
    ...
    delete[] &x;
    return 0;
}

Which you could easily turn into a more generic solution:

template<typename T, int x, int y>
struct Array2D
{
    typedef T CArrayType[x][y];
    typedef CArrayType& RefType;
    static CArrayType& New()
    {
        return *(reinterpret_cast<CArrayType*>(new T[x * y]));
    }
    static void Delete(RefType x)
    {
        delete[] &x;
    }
};

typedef Array2D<double, 3, 4> MyGrid;// define your 2d array with 3 rows / 4 columns.

int main(int argc, char* argv[])
{
    MyGrid::RefType j = MyGrid::New();
    ...
    j[1][2] = 0.3333;
    ...
    MyGrid::Delete(j);
    return 0;
}

The idea is to just generate the elements in 1D (x*y), and cast it to a 2D array. But since array types are value types, you need to deal in pointers-to-arrays. Using a reference makes it almost transparent.

Boost probably has something like this but I don't know boost well enough to say...

tenfour
  • 36,141
  • 15
  • 83
  • 142