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

时间:2019-03-12 03:47:02

标签: c multidimensional-array struct

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

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

我对为什么它适用于29000但不能适用于30000感到非常困惑。此外,如果有人对如何malloc一行存储数组有任何建议,而不必进入2进行循环,我会很高兴学习。我也想知道我是否应该在这里使用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;

3 个答案:

答案 0 :(得分:1)

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

您可能已经想到*arrayofnodes[p][j] -在行p和列j处为指向结构的指针分配空间。请注意,这不包括char *所指向的存储块的空间,该空间也需要malloc进行编辑。

另外,请记住,尽管堆有足够的空间,但堆栈却没有,8 * 35 * 30000可能超出了堆栈框架的处理能力。

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

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

通过维对数组进行平铺,并使用偏移量查找特定的行/列是另一种选择。长话短说,有很多方法可以解决此问题,其中很多取决于您的数据以及您打算如何使用它。

此外,使用完毕后,请不要忘记free()

答案 1 :(得分:1)

问题很可能是您在堆栈上分配了很多东西。 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("%d\n", 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));
}

答案 2 :(得分:0)

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

您可以通过使用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...
}