开发者

Assign to 2D array a 2D array in a struct

I have a开发者_JAVA百科 function which tries to loop through a 2D array in a struct:

typedef struct node
{
    int grid[3][3];
} Node;


void someFunction(Node *node) {
     int grid[3][3] = node->grid;
     //loop through
}

When I try to compile this however I get a

mp.c:42: error: invalid initializer


You cannot assign arrays in C. It is simply not allowed. When you wrote:

int grid[3][3] = node->grid;

you were attempting to initialize the local array, grid, from the passed in node. If that were permitted (which it isn't), then you'd not need a loop afterwards.

You can assign structures, though, even if they contain arrays, so if the local structure were a Node, you could have written:

Node local = *node;

You would not need to loop through the arrays afterwards to initialize local.

You can loop through the arrays, doing the copy one element at a time:

for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
        grid[i][j] = node->grid[i][j];

You can also use memmove() or memcpy():

int grid[3][3];

assert(sizeof(grid) == sizeof(node->grid));
memcpy(grid, node->grid, sizeof(grid));

At one time, another answer suggested:

Change the line:

int grid[3][3] = node->grid;

to:

int **grid = node->grid;

I noted that this will not work - and was legitimately challenged to explain why. That requires space and formatting.

First of all, the compiler notes:

warning: initialization from incompatible pointer type

That is saying 'you are playing with fire'.

Let's suppose we ignore that warning. The local grid now points at the top-left corner of the array (if you see arrays growing down and across from left-to-right). The value stored there is a plain number, not an initialized pointer, but when the compiler evaluates grid[0], it is forced to assume that will produce a pointer. If node->grid[0][0] contains a zero, you will probably get a segmentation fault and core dump for dereferencing a null pointer (on the assumption that pointers and int are the same size, which is generally true on 32-bit systems), or some other undefined behaviour. If node->grid[0][0] contains another value, then the behaviour is still undefined, but not quite as predictable.


If you don't want to do the copy, just want a pointer to the array in the struct (note: if you assign values to *pointer, the content of the array in the struct will be changed), you can achieve this aim in two ways:

#include <stdio.h>

typedef struct node
{
    int grid[3][3];
} Node;


void someFunction1(Node *node) {
     int i, j;
     int (*grid)[3] = node->grid;
     for(i=0; i<3; i++){
         for(j=0; j<3; j++){
             printf("%d ", grid[i][j]);
         }
         printf("\n");
     }
}

void someFunction2(Node *node) {
     int i, j;
     int *grid = (int*) node->grid;
     for(i=0; i<3; i++){
         for(j=0; j<3; j++){
             printf("%d ", grid[i*3+j]); // i * column_number + j
         }
         printf("\n");
     }
}

int main()
{
    Node t;
    int i, *p;

    //initialization: t.grid[0][0]=0,  ..., t.grid[2][2]=8
    for(i=0, p=(int*)t.grid; i<9; p++, i++){
        *p = i;
    }

    printf("Function1:\n");
    someFunction1(&t);

    printf("Function2:\n");
    someFunction2(&t);

    return 0;
}

The above code shows a simple function to use pointers. They are all safe and up to standard.

If you want to use pointer to pointer, int**, you will have to make it in a different way, because, arrays are linear storage in memory (so the above code can use an int* to point to the beginning of the array and operate it), but int** not.

EDIT

So here comes the someFunction3()

void someFunction3(Node *node)
{
    int i, j;
    int **p;

    // 3 is the row number. Ignore checking malloc failure
    p = malloc(sizeof(int)*3);
    for(i=0; i<3; i++) {
        p[i] = (int*) node->grid[i]; //assign address of each row of array to *p
    }

    for(i=0; i<3; i++) {
        for(j=0; j<3; j++) {
            printf("%d ", p[i][j]);
        }
        printf("\n");
    }

    free(p);
}


See this other thread for the same question and the answer that doesn't involve copying the memory:

Create a pointer to two-dimensional array

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜