开发者

Returning a 2D array or a pointer to one

If a 2d array is created int 2DRepresentation[mapWidth][mapHeight]; inside a function, what is the best way to return this?

开发者_如何学C

how does the function return look?

Would it be preferred to rather create a pointer to a 2d array and pass it into a function, modifying it within the function? If so, how does a pointer to a 2D array look? Like this:

int *2DRepresentation[mapWidth][mapHeight]; ?

How would the function parameter look like which accepts a 2d array pointer?


You will have to return the base address of the array, i.e., a Pointer. However the only solution is that you will have to make the array static otherwise once the function goes out of scope, it will get destroyed. If you don't want to make it static you should use dynamic memory allocation.

Sample pseudo-code:

    int **array; // array is a pointer-to-pointer-to-int
    array = malloc(mapHeight * sizeof(int *));
    if(array == NULL)
        {
        fprintf(stderr, "out of memory\n");
        exit or return
        }
    for(i = 0; i < mapHeight ; i++)
        {
        array[i] = malloc(mapWidth * sizeof(int));
        if(array[i] == NULL)
            {
            fprintf(stderr, "out of memory\n");
            exit or return
            }
        }

This is how you might pass it into a function named foo say:

foo(int **array, int _mapHeight, int _mapWidth)
    {
    }

Arrays decay into pointers, hence you need to pass the rows and column values as separate arguments.


If a 2d array is created "int 2DRepresentation[mapWidth][mapHeight];" inside a function, what is the best way to return this?

If it is created inside a function as the way you represented ( assuming mapWidth, mapHeight are constants ), it should not be returned. Because it resides on stack and goes out of scope upon the function return and returning a reference of it just points to garbage.


Would it be preferred to rather create a pointer to a 2d array and pass it into a function, modifying it within the function?

Yes, you are correct.

how would the function parameter look like which accepts a 2d array pointer?

Example:

void foo( int twoDimensionalArray [][3] )
{

    // Now you can modify the array received.

}

int main()
{
     int ar[3][3] ;
     foo(ar) ;
     // .....
}

Or you can dynamically allocate memory in side foo and return a reference of it.

int** foo()
{
    // ....
    return mallocatedTwoDimensionalArray ;
}


For the array to persist in memory, it either needs to be declared static or it should be explicitly allocated using malloc or calloc (each solution has functionality implications--i.e. the static version will be overwritten the next time the function is called, and the allocated version needs to be explicitly freed later to avoid memory leaks).

Note that pointers and arrays are not the same thing in C, and since you're dealing with dynamic allocation in the malloc case, you'll be working with pointers. Referencing array elements using these pointers will be functionally the same as referencing array elements, so you shouldn't notice a difference once the array has been created.

Here is an example that allocates, populates and returns a 2D array using a single malloc (both for the sake of efficiency, and to allow the use of a single free for deallocation):

int **get2dArray(int rows, int cols)
{
    int **array2d;
    int i, j, offset;
    int *gridstart;

    offset = rows * sizeof(int *);

    array2d = malloc( offset + rows*cols*sizeof(int) );

    /* Demote to char for safe pointer arithmetic */
    gridstart = (int *)((char *)array2d + offset); 

    for ( i = 0; i < rows; i++ ) {
        /* Point to the proper row */
        array2d[i] = gridstart + i*cols;

        /* Populate the array -- your code goes here */
        for ( j = 0; j < cols; j++ ) {
            array2d[i][j] = i*cols + j;
        }
    }

    return array2d;
}


int main ( int argc, char **argv )
{
   int **testarray;

   testarray = get2dArray( 10, 100 );

   /* Verify that addressing and population went as planned */
   printf( "%d %d %d %d %d %d\n", testarray[0][0], testarray[2][55], 
           testarray[4][98], testarray[5][0], testarray[7][15], 
           testarray[9][99] );   

   free(testarray);

   return 0;
}

There are many other ways to do this, but this demonstrates a function that will return a 2D pointer "array".


It is better to define the array outside the function and pass it in.

Remember that an array, when used as a function argument, decays into a pointer to its first element and therefore, inside the function, it is a pointer and has no information about the original size. You need to pass the size too.
If you have a C99 compiler, you can use a "variably modified parameter" (see 6.7.5.3):

int func(int rows, int cols, int data[rows][cols]) {
    int sum = 0;
    for (int row = 0; row < rows; row++) {
        for (int col = 0; col < cols; col++) {
            sum += data[row][col];
        }
    }
    return sum;
}

and call it with, for example:

int main(void) {
    int a[42][100] = {0};
    if (func(42, 100, a) == 0) /*ok*/;

    int b[1000][2] = {0};
    if (func(1000, 2, b) == 0) /*ok*/;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜