如何动态分配一个结构体的二维数组?

6

因为编译时无法确定维度,所以我试图动态分配一个二维结构数组。代码可以编译,但在访问元素时出现了错误访问。

// The struct
typedef struct
{
    NSInteger numActors;
    Actor *a1;
    Actor *a2;
    Actor *a3;
    Actor *a4;
    Actor *a5;
} GridNode;

// In interface
GridNode **grid;

// In init
NSInteger nx = inFrame.size.width / blockSize;
NSInteger ny = inFrame.size.height / blockSize;
grid = malloc(sizeof(GridNode) * nx * ny);
grid[10][20].numActors = 3; // EXC_BAD_ACCESS

nx和ny的值是多少?你确定它们是你想要的吗? - WildCrustacean
当我测试时,nx和ny都是128。 - Morrowless
4个回答

7

C语言只有一维数组,因此可以用两种方式定义二维数组:

  1. As an array of arrays, like GridNode **grid, so to be accessed by grid[x][y], but then you have to init each row separately (right, as yehnan managed to anwser first):

    grid=malloc(sizeof(GridNode*)*nx);  
    for(int e=0;e<nx;e++) grid[e]=malloc(sizeof(GridNode)*ny);
    
  2. As a 1D array with tricky indexing:

    grid=malloc(sizeof(GridNode)*nx*ny);  
    grid[(10-1)*nx+20] //grid[10,20]
    

6
大致上,代码应该看起来像这样:

grid = (GridNode **) malloc(sizeof(GridNode *) * nx);
int i;
for(i = 0; i < nx; i++) {
    grid[i] = (GridNode *) malloc(sizeof(GridNode) * ny);
}

记得将它们释放。


谢谢,我现在看到错误了。 - Morrowless
在这种情况下,我该如何释放它们? - Potion

1
一个更简单的方案是创建一个单维的NSArray或者NSMutableArray,然后通过一些数学计算来定位正确的行和列:
NSUInteger width  = 10;
NSUInteger height = 10;
NSUInteger size   = width * height;
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:size];

要在第5行第3列插入一个GridNode,您可以这样做:

NSUInteger index = (row - 1) * width + col;
[array insertObject:myNode atIndex:index];

要从第2行第6列检索节点,您需要执行以下操作:
NSUInteger index = (row - 1) * width + col;
[array objectAtIndex:index];

你计算机的内存是单维的。我们从C语言中熟悉的多维寻址实际上只是一种语法糖,它执行了与我上面展示的类似操作。

我能想到的唯一注意事项是,你可能需要将GridNode从C结构转换为Objective-C类才能使其正常工作。


0

你的分配概念是错误的。

假设x是你的第二维度(例如你的示例中的[20]),y是你的第一维度(例如你的示例中的[10]),那么y元素只是指向x数组的指针。因此,在概念上,你应该这样做:

哎呀,yehnan比我先说了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接