我正在尝试创建一个二维数组,每个元素都指向一个结构来存储 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 node
或sizeof 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...
}