By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,146 Members | 1,631 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,146 IT Pros & Developers. It's quick & easy.

Initializing multi-dimensional array in constructor

P: n/a
I'm having a ton of trouble initializing a multi-dimensional array
inside a constructor, largely because I don't know the size of the
array until runtime. I have a class that looks like this:

class MyClass
{
public:
const int size;
MyClass( const int );
};

MyClass::MyClass( const int s )
: size( s )
{
int (*arrayPtr)[size][size] = new int[size][size][size];
}

When I compile this with g++ (actually, Apple's version of g++, in case
that matters), I get the following error:
myclass.cpp : In constructor 'MyClass::MyClass(int)':
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression

Can anyone explain why I'm getting this error message, especially since
size is declared const, and also can anyone help me out with what to do
about it? Thanks.

--Jay

Jul 24 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a
ja*******@gmail.com wrote:
I'm having a ton of trouble initializing a multi-dimensional array
inside a constructor, largely because I don't know the size of the
array until runtime. I have a class that looks like this:

class MyClass
{
public:
const int size;
MyClass( const int );
};

MyClass::MyClass( const int s )
: size( s )
{
int (*arrayPtr)[size][size] = new int[size][size][size];
}

When I compile this with g++ (actually, Apple's version of g++, in
case that matters), I get the following error:
myclass.cpp : In constructor 'MyClass::MyClass(int)':
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression

Can anyone explain why I'm getting this error message, especially
since size is declared const, and also can anyone help me out with
what to do about it? Thanks.
Please see the FAQ. Creation of multidimensional dynamic arrays is
actually covered in it.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 24 '06 #2

P: n/a
Jay Harris posted:

int (*arrayPtr)[size][size] = new int[size][size][size];

You're going to need to employ more devious tactics, something like:

(I've written this hastily in the last half hour, so expect bugs.)
#include <cassert>

template<class T>
class Accessor2D {
protected:

T *const p;
unsigned const d2;

public:

Accessor2D(T *const parg,unsigned const arg2) : p(parg), d2(arg2)
{
assert(parg);
assert(arg2);
}

T *operator[](unsigned const arg2)
{
assert(arg2);

return p + (arg2 * d2);
}
};
template<class T>
class Accessor3D {
protected:

T *const p;
unsigned const d2;
unsigned const d3;

public:

Accessor3D(T *const parg,unsigned const arg2, unsigned const arg3)
: p(parg), d2(arg2), d3(arg3)
{
assert(parg);
assert(arg2);
assert(arg3);
}
Accessor2D<Toperator[](unsigned const arg1)
{
assert(arg1);

return Accessor2D<T>( p + (arg1 * d2 * d3), d3 );
}
};
/* Now here comes your class */
class MyClass {
public:
unsigned const size;
MyClass(unsigned const);
};

MyClass::MyClass(unsigned const s) : size(s)
{
Accessor3D<intarr(new int[size*size*size],size,size);

arr[0][0][0] = 5;

arr[0][1][2] = 7;
}

int main()
{
MyClass obj(7);
}

--

Frederick Gotham
Jul 24 '06 #3

P: n/a
ja*******@gmail.com wrote:
I'm having a ton of trouble initializing a multi-dimensional array
inside a constructor, largely because I don't know the size of the
array until runtime. I have a class that looks like this:
"Size" portion of array types in C++ must be a so called 'integral constant
expression' (ICE). The exact definition of ICE can be found in the language
specification, but the idea is that the size must be known at compile time.
Non-static class data members cannot be used in ICEs. This is what makes the
compiler to complain.

Since in your case array sizes are only known at run-time, there's no way to
achieve what you want with array type or type derived from array type (as the
'int (*)[size][size]' you are trying to use). There are different ways to solve
the problem:

1. Use a 1D array of size 'size * size * size' and simulate a 3D access by
manually transforming the 3D indices into the corresponding the 1D index:

[x][y][z] - [x * size * size + y * size + z]

(that's, BTW, how built-in arrays work in C/C++)

2. Use the well-known array-of-pointers idiom:

int*** arrayPtr = new int**[size];
// Then for each i
arrayPtr[i] = new int*[size];
// Then for each i, j
arrayPtr[i][j] = new int[size];

(the above is just an illustration of the idea; the actual implementation can be
done in a neater way).

3. (Might make the most sense out of three) Use
'std::vector<std::vector<std::vector<int >'.
class MyClass
{
public:
const int size;
MyClass( const int );
};

MyClass::MyClass( const int s )
: size( s )
{
int (*arrayPtr)[size][size] = new int[size][size][size];
}

When I compile this with g++ (actually, Apple's version of g++, in case
that matters), I get the following error:
myclass.cpp : In constructor 'MyClass::MyClass(int)':
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression
--
Best regards,
Andrey Tarasevich
Jul 24 '06 #4

P: n/a
Thanks. Option 1 seemed the simplest, so I went with it.

Andrey Tarasevich wrote:
ja*******@gmail.com wrote:
I'm having a ton of trouble initializing a multi-dimensional array
inside a constructor, largely because I don't know the size of the
array until runtime. I have a class that looks like this:

"Size" portion of array types in C++ must be a so called 'integral constant
expression' (ICE). The exact definition of ICE can be found in the language
specification, but the idea is that the size must be known at compile time.
Non-static class data members cannot be used in ICEs. This is what makes the
compiler to complain.

Since in your case array sizes are only known at run-time, there's no way to
achieve what you want with array type or type derived from array type (as the
'int (*)[size][size]' you are trying to use). There are different ways to solve
the problem:

1. Use a 1D array of size 'size * size * size' and simulate a 3D access by
manually transforming the 3D indices into the corresponding the 1D index:

[x][y][z] - [x * size * size + y * size + z]

(that's, BTW, how built-in arrays work in C/C++)

2. Use the well-known array-of-pointers idiom:

int*** arrayPtr = new int**[size];
// Then for each i
arrayPtr[i] = new int*[size];
// Then for each i, j
arrayPtr[i][j] = new int[size];

(the above is just an illustration of the idea; the actual implementation can be
done in a neater way).

3. (Might make the most sense out of three) Use
'std::vector<std::vector<std::vector<int >'.
class MyClass
{
public:
const int size;
MyClass( const int );
};

MyClass::MyClass( const int s )
: size( s )
{
int (*arrayPtr)[size][size] = new int[size][size][size];
}

When I compile this with g++ (actually, Apple's version of g++, in case
that matters), I get the following error:
myclass.cpp : In constructor 'MyClass::MyClass(int)':
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression

--
Best regards,
Andrey Tarasevich
Jul 26 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.