简体   繁体   中英

C99 How to cast simple pointer to a multidimensional-array of variable length?

In my function bodies reduce() and initialize(...) I want to work with the array globalArray as a three-dimensional one, where the dimensions are not known until runtime.

How do I cast the globalArray pointer to a variable-length array (pointer) and use it naturally? I think the typedef approach helps, but I'm still lost. This current version compiles and seemingly works after my tinkering. Are Cast #1 and Cast #2 as clear and safe as can be achieved?

#include <stdlib.h>
#include <stdio.h>

double * globalArray; /* working from a situation where the array is global, declared elsewhere */
int M, N, P; /*array dimensions not known until runtime */

double reduce();
double reduce()
{
    /* Here I want to re-interpret the one-dimensional globalArray into
       a multi-dimensional variable-length array so that compiler takes
       care of the indexing math for me.*/
    typedef double (*arr_t)[N][P];

    const arr_t castArray = (arr_t)globalArray;  /* Cast #1 */

    double sum=0.0;
    for (int i=0; i<M; i++)
        for (int j=0; j<N; j++)
            for (int k=0; k<P; k++)
                sum += castArray[i][j][k];
    return sum;
}

void initialize(int M, int N, int P, double threedimarray[M][N][P])
{
    for (int i=0; i<M; i++)
        for (int j=0; j<N; j++)
            for (int k=0; k<P; k++)
                threedimarray[i][j][k] = (double)(i*N*P + j*P + k);
}

int main(int argc, char **argv)
{
    M = 10; N=1000; P=200;
    globalArray = malloc( M*N*P* sizeof(double) );

    typedef double (*arr_t)[N][P];
    initialize(M, N, P, (arr_t)globalArray); /* Cast #2 */

    double result = reduce();
    printf("Reduced result: %f\n", result );
    return 0;
}

https://ideone.com/5Y8Q64

I'm reworking a small section of a large program. There are clearly better design approaches than program scope array pointers. It is what it is. From a self-documenting point-of-view, it'd be nice if the solution doesn't throw away the fact that we "know" the extent of the leading dimension (M) as well.

The similar SO questions relating to function argument declarations are helpful but I'm not connecting the dots I guess. I decided to ask here hoping the answer will reach more people.

Here's one possible casting solution I've arrived at after some tinkering.

typedef double (*arr_t)[N][P];
arr_t castArray = (arr_t)globalArray;

/* Now castArray can be accessed by multi-dimensional index notation */
castArray[i][j][k] = 3.14;

Downsides:

1) Does not self-document known leading dimension length M .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM