C 中的二维结构数组??(也许吧)



我正在尝试创建一个二维数组,每个元素都指向一个结构来存储 CSV 文件中的值。我不确定我是在创建结构还是定义 2d 数组。

下面是我的结构以及我如何分配内存。将始终有 35 列,但行可能会变得很大。当我使用 int test =29000(或 29000 行)运行它时,它可以工作并将所有值存储在我可以通过[row][col]访问的 2d 数组中。当我使用大于 29000 的任何值分配测试时,它会 seg 错误,甚至没有进入模因的分配,它只是在struct node* arrayofnodes[test][35];处出现段错误

我很困惑为什么它适用于 29000 而不是 30000。另外,如果有人对如何在一行上malloc数组而不必进入 2 for 循环有任何建议,我将非常乐意学习。我也想知道我是否应该在这里使用typedef struct

谢谢

struct node {
char* value;
};
int test=30000;
struct node* arrayofnodes[test][35];
for (int p=0; p < test; p++){
for (int j=0; j < 35; j++){
arrayofnodes[p][j] = malloc(sizeof(arrayofnodes));
}
}//this works and i can access a certain element by arrayofnodes[row][col].value;

问题可能是您在堆栈上分配了很多。arrayofnodes将是一个包含 30,000*35=1,050,000 个指针的数组,每个指针可能是 8 个字节。因此,您尝试在堆栈上分配一个 8MB 的数组,而 8MB 是堆栈大小的默认限制。

这段代码为我截断了:

#include <stdio.h>
int main() {
struct node {
char* value;
};
int test=30000;
struct node* arrayofnodes[test][35];
printf("%dn", sizeof(arrayofnodes));
}

此外,sizeof(arrayofnodes)是错误的。如果上面的代码片段没有段错误,它会打印8400000。相反,sizeof struct nodesizeof arrayofnodes[0][0]会给出正确的结果。

解决方案可能是这样的:

struct node ** array[35];
for(int i=0; i<35; i++) {
array[i] = malloc(test * sizeof array[0]);
for(int j=0; j<test; j++) array[i][j] = malloc(sizeof (struct node));
}

您在此处分配了大量内存:printf("%lun", sizeof(arrayofnodes));报告arrayofnodes的大小为30000 * 35 * 8 = 8400000字节,因此循环中的总内存分配为30000 * 35 * 8400000 = 8820000000000个字节。

您可能的意思是*arrayofnodes[p][j]--为指向第p行和列j处结构的指针分配空间。请注意,这不包括char *指向的内存块的空间,这也需要进行malloc编辑。

另外,请记住,虽然堆有足够的空间,但堆栈没有,8 * 35 * 30000可能超过堆栈帧可以处理的空间。

如果只有一个字段,请考虑避免使用结构。使用普通的旧char *可以避免额外的间接层。

如果您想以牺牲速度为代价来最大化空间效率,您可以尝试读取一次文本文件,为每个单元格构建一个字符串大小的数组,然后相应地malloc所有内容以进行第二次传递。您可以使用包含分配给大小csv_cell_size[row][col]或类似大小的单元格的char ***csv_data数组。

按维度展平数组并使用偏移量查找特定行/列是另一种选择。长话短说,有很多方法可以管理它,很大程度上取决于您的数据以及您计划如何使用它。

另外,当您完成它时,不要忘记free()所有内存。

您的数组声明正在堆栈上分配,默认堆栈限制为 8MB。当测试为 29000 时,堆栈分配在限制 (29000 * 35 * 8 = 7.7MB) 内,当您将测试更改为 30000 时,您超过了堆栈限制 (30000 * 35 * 8 = 8.01MB),这会导致 int seg 错误。

您可以通过使用 malloc 在堆上分配数组来解决这个问题,只需记住释放您分配的内容即可。

#include <stdio.h>
#include <malloc.h>
struct node {
char *value;
};
int rows = 30000;
int cols = 35;
struct node **arrayofnodes;
int main() {
arrayofnodes = (struct node **)malloc(rows * sizeof(struct node*));
for (int row = 0; row < rows; row++) {
arrayofnodes[row] = (struct node *)malloc(cols * sizeof(struct node*));
}
// Use arrayofnodes
// Free allocations after use...
}

最新更新