murphy2902
murphy2902

Reputation: 67

How do I pass a multi-dimensional array of variable size in C?

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.

Upvotes: 1

Views: 211

Answers (4)

Lee Daniel Crocker
Lee Daniel Crocker

Reputation: 13171

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.

Upvotes: 0

M Oehm
M Oehm

Reputation: 29126

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++.

Upvotes: 2

user12205
user12205

Reputation: 2702

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]) {

}

Upvotes: 1

doron
doron

Reputation: 28902

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.

Upvotes: 3

Related Questions