2

Sorry if this is a noob question, but I'm currently learning C++. I have a function that takes in several parameters - I would like to use those parameters when creating a 3D int array.

void* testFunction(int countX, int countY, int countZ)
{
    const int NX = countX;
    const int NY = countY;
    const int NZ = countZ;

    int* data_out = new int*[NX][NY][NZ]; 
    // The above line throws the error on "NY" - expression must
    // have a constant value
}

From various posts I've learned that you must allocate the array first but I guess I'm doing that wrong? How do you properly initialize a multidimensional array. Also, why does the initialization require a pointer?

5
  • 4
    Ideally you should use a 1 dimensional vector or unique_ptr<T[]> and fake the three dimensions using math. Commented Jan 4, 2017 at 19:14
  • @MichaelO.Your suggestion still throws the same "expression must have a constant value" error. EDIT: The "const int NZ - countZ" was a type - I edited the post to have the proper "=". Commented Jan 4, 2017 at 19:15
  • 1
    Short answer: You can't do this. Long answer: You shouldn't do this. Arrays are the wrong tool, because they do not track their own size. See NathanOliver's comment. Commented Jan 4, 2017 at 19:21
  • @NathanOliver do any of you know where I can find a simple example that illustrates this concept? Commented Jan 4, 2017 at 19:31
  • 2
    @Roka545 see: stackoverflow.com/questions/3902648/… Commented Jan 4, 2017 at 19:33

1 Answer 1

2

To explain the error: C++ requires a name of a type in its new operator. A name of a type cannot have runtime dimensions, because all types in C++ are static (determined at compilation time).

For example, this allocates 3 elements of type int[4][5]:

new int[3][4][5];

Another example: this allocates NX elements of type int[4][5]:

new int[NX][4][5];

An incorrect example: this would allocate NX elements of type int[NY][NZ], if C++ had support for "dynamic" types:

new int[NX][NY][NZ];

To allocate a 3-dimensional array, or something that looks like it, you can use std::vector:

std::vector<std::vector<std::vector<int>>> my_3D_array;
... // initialization goes here
my_3D_array[2][2][2] = 222; // whatever you want to do with it

To make the syntax less verbose, and streamline the initialization, use typedef (or here using, which is the same):

using int_1D = std::vector<int>;    // this is a 1-dimensional array type
using int_2D = std::vector<int_1D>; // this is a 2-dimensional array type
using int_3D = std::vector<int_2D>; // this is a 3-dimensional array type
int_3D data(NX, int_2D(NY, int_1D(NZ))); // allocate a 3-D array, elements initialized to 0
data[2][2][2] = 222;

If you want to return this array from your function, you should declare it; you cannot just return a void pointer to the data variable. Here is a syntax of a declaration:

using int_1D = std::vector<int>;
using int_2D = std::vector<int_1D>;
using int_3D = std::vector<int_2D>;
int_3D testFunction(int countX, int countY, int countZ)
{
    int_3D data(...);
    ...
    return data;
}

That is, instead of using new, just use std::vector<whatever> as if it were any other type.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.