将2D数组分配给结构中的2D数组

时间:2011-07-21 01:49:26

标签: c

我有一个函数试图循环结构中的2D数组:

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


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

当我尝试编译时,我得到了一个

  

mp.c:42:错误:初始化程序无效

3 个答案:

答案 0 :(得分:11)

您无法在C中分配数组。这是不允许的。当你写道:

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

您试图从传入的grid初始化本地数组node。如果允许(不是这样),那么之后就不需要循环了。

你可以分配结构,即使它们包含数组,所以如果本地结构是Node,你可以写:

Node local = *node;

之后您无需循环遍历数组以初始化local

您可以遍历数组,一次复制一个元素:

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

您还可以使用memmove()memcpy()

int grid[3][3];

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

有一次,另一个答案建议:

  

更改行:

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

为:

int **grid = node->grid;

我注意到这不起作用 - 并且合理地挑战解释原因。这需要空间和格式。

首先,编译器注意到:

warning: initialization from incompatible pointer type

那就是说'你正在玩火'。

我们假设我们忽略了这个警告。本地grid现在指向数组的左上角(如果您看到数组从左到右逐渐增长)。存储在那里的值是一个普通数字,而不是一个初始化的指针,但是当编译器评估grid[0]时,它被强制假设会产生一个指针。如果node->grid[0][0]包含零,则可能会出现分段错误和核心转储以取消引用空指针(假设指针和int的大小相同,这通常适用于32位系统),或其他一些未定义的行为。如果node->grid[0][0]包含另一个值,那么行为仍未定义,但不太可预测。

答案 1 :(得分:1)

如果你不想复制,只需要一个指向结构中数组的指针(注意:如果你将值赋给*pointer,结构中数组的内容将会改变) ,你可以通过两种方式实现这一目标:

#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;
}

上面的代码显示了一个使用指针的简单函数。它们都是安全且符合标准的。

如果你想使用指向int**的指针,你将不得不以不同的方式使用它,因为,数组是内存中的线性存储(所以上面的代码可以使用int*指向数组的开头并操作它,但int**没有。

修改

所以这里是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);
}

答案 2 :(得分:0)

请参阅此另一个主题以获取相同问题以及不涉及复制内存的答案:

Create a pointer to two-dimensional array