1

I'm trying to pass an three dimensional array to a function like this:

void example( double*** bar ) {
    // Stuff
}

int main() {
    double[3][2][3] foo;
    // Initialize foo
    example( foo );
    return 0;
}

This causes the gcc to give me "Invalid pointer type". How am I supposed to be doing this? I could just make the entire argument a one-dimensional array and arrange my data to fit with that, but is there a more elegant solution to this?

edit:

In addition, I can't always specify the length of each sub-array, because they may be different sizes. e.g.:

int* foo[] = { { 3, 2, 1 }, { 2, 1 }, { 1 } };

If it helps at all, I'm trying to batch pass inputs for Neurons in a Neural Network. Each Neuron has a different number of inputs.

5
  • About the second part of your question: You can create a function void example(int *bar[]) and pass foo, but correctly processing bar is just as difficult as correctly processing foo. One simple solution would be including a "stop marker" in the array, e.g. int* foo[] = { { 3, 2, 1, -1 }, { 2, 1, -1 }, { 1, -1 }, { -2 } }; (but please replace the magic numbers with symbolic constants!) Commented May 4, 2015 at 19:28
  • How do you tell the length of each sub-array if they're of different lengths? Commented May 4, 2015 at 19:34
  • You just process the sub-arrays till you hit -1; there is no way to directly get the length of the sub-arrays, since that information is simply not available at runtime, C doesn't keep it anywhere. Commented May 4, 2015 at 19:40
  • I have it stored myself. Each neuron keeps the number of inputs it's expecting, so I use that. The function that handles all of this works, theoretically, I just need to figure out how to correctly make a double*** Commented May 4, 2015 at 19:47
  • See this answer of mine for a structure that encapsulates the dimensions and can be passed to functions. Commented May 5, 2015 at 4:35

4 Answers 4

3

just use double*. A multidimensional array is stored contiguously in memory so you are quite welcome to give it your own stride. This is how bitmaps are passed on OpenGL.

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

3 Comments

Could I cast this into a multidimensional array within the function?
Nothing to stop you. The only thing is that you will probably lose the ability to determine the various dimensions at runtime. It is probably a much better idea to do your own stride calculations. That way the sizing of the x,y,z dimensions can all be done at runtime.
I've done a lot of testing, and I think this is the one that works the best for me. Thanks!
2

A one-dimensional int array decays into an int pointer when passing it to a function. A multi-dimensional array decays into a pointer to an array of the next lowest dimension, which is

void example(double (*bar)[2][3]);

This syntax can be a bit baffling, so you might chose the equivalent syntax:

void example(double bar[][2][3]) {
    // Stuff
}

int main() {
    double foo[3][2][3];

    example(foo);
    return 0;
}

The first dimension does not have to be given, it's that part that is "decaying". (Note that the dimensions of arrays are not given on the type as in Java, but on the array name.)

This syntax works for variable-length arrays (VLAs) as well, as long as you pass the dimensions before the array:

void example(int x, int y, double (*bar)[x][y]) {
    // Stuff
}

int main() {
    double foo[3][2][3];

    example(2, 3, foo);
    return 0;
}

This feature requires C99 and is not compatible with C++.

1 Comment

This is really informative! Unfortunately, I didn't explain that each sub-array may be a different length as well. I've edited the question to include that.
1

If the array size is fixed, you can use:

void example(double bar[][2][3]) {

}

Otherwise, you can pass the size along with the array into the function:

void example(size_t x, size_t y, size_t z, double bar[x][y][z]) {

}

5 Comments

this does force you into fixed size arrays
@doron Updated to include variable-length array method.
I apologize, I forgot to mention that some of the arrays have different sizes within the other arrays. eg: int* foo[3] = { { 3, 2, 1 } , { 2, 1 }, { 1 } }
@ace, can one do this at runtime?
@doron If you're referring to the OP's initialization statement, probably not.
0

That can't be done in C the way you're thinking of. If you need a function that operates on variable-size multidimensional arrays, you'll either have to pass the sizes (all but one) explicitly to the function, or make a structure and pass that. I generally always make a structure when a 2D or 3D array is called for, even if they're of fixed size. I think it's just cleaner that way, since the structure documents itself.

1 Comment

I've been thinking about this as well. I may try this as well as a single-dimensional array, and see which one is easier to use.

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.