每个包含动态数组的结构数组

时间:2014-03-01 07:58:51

标签: c arrays pointers dynamic struct

我对C语言有点精通,我认为在遇到这个问题之前我已经找到了所有指针。我正在创建一个数组实现的结构堆栈。很容易,但是当我的struct包含一个动态分配的数组时,我遇到了一个问题。

结构是:

typedef struct state {
    int* S;
    double prob;
} state_t;

现在说我想创建一个包含10个结构的数组,每个结构都有一个整数数组,比如5个整数。我可以将该数组分配为:

state_t *newContents;
newContents = (state_t *)malloc((sizeof(state_t) + 5 * sizeof(int)) * 10);

我可以在第一个插槽中创建一个结构:

state_t *root = malloc(sizeof *root + 5 * sizeof(int));
root->prob = 1.0;
root->S[0] = 3;
root->S[1] = 5;
root->S[2] = 7;
root->S[3] = 2;
root->S[4] = 0;
newContents[0] = *root;

但是当我尝试添加第二个结构时,Seg错误。这是因为数组索引的方式是没有int数组的struct的大小,这意味着每个条目的长度为16个字节 - 对于指针的双精度数为8,为8。我希望它代之以28 - 8为双,而4 * 5为整数。有没有人知道如何正确访问这个数组的元素?

谢谢!

3 个答案:

答案 0 :(得分:4)

你的结构错误分配。结构本身与其动态分配的数组是分开的,需要单独分配:

// Allocate the structs.
state_t *newContents = malloc(10*sizeof(*newContents));

// Allocate the S array of the first struct.
newContents[0].S = malloc(5*sizeof(int));
newContents[0].S[0] = 3;
...

如果你想要一个实际上包含一个运行时确定长度数组的结构,而不是像当前结构那样指向一个结构,那么你需要一个灵活的数组成员:

struct state_t {
    double prob;
    int S[]; // No length specified!
};

然后你可以malloc(sizeof(state_t) + n*sizeof(int))并实际获得一个连续的内存块,其中struct和它的数组在一起。但是,如果执行此操作,则无法正确地生成state_t数组,因为编译器不知道一个结构在哪里结束而另一个结构开始。

答案 1 :(得分:2)

这样做:

state_t *newContents;
newContents = malloc(sizeof(state_t)*10);

int i;
for (i=0;i<10;i++)
   (newContents+i)->S=malloc(5 * sizeof(int));

如果希望newContents是大小为10的结构数组,那么它应该分配大小等于sizeof(state_t)*10。应明确分配每个结构中的int *

答案 2 :(得分:1)

使用

  1. Arrays of Length Zero及其GCC扩展
  2. 适当的铸造
  3. 正确的指针算法
  4. 你可以或多或少得到你想要的东西。

    这是我的测试程序(使用gcc -std=c99进行编译):

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct state {
        double prob;
        int S[];
    } state_t;
    
    int main(void) {
        size_t stateSize;
        state_t *newContents;
        stateSize = sizeof(state_t) + 5*sizeof(int);
        newContents = malloc(stateSize * 10);
    
        for (int i = 0; i < 10; i++) {
            state_t *state = (state_t *)((char *)newContents + i * stateSize);
            state->prob = i;
            for (int j = 0; j < 5; j++) {
                state->S[j] = i * j;
            }
        }
    
        for (int i = 0; i < 10; i++) {
            state_t *state = (state_t *)((char *)newContents + i * stateSize);
            printf("[%d] prob: %f\n", i, state->prob);
            for (int j = 0; j < 5; j++) {
                printf("\tS[%d]: %d\n", j, state->S[j]);
            }
        }
    }
    

    执行命令

    $ ./a.out 
    [0] prob: 0.000000
        S[0]: 0
        S[1]: 0
        S[2]: 0
        S[3]: 0
        S[4]: 0
    [1] prob: 1.000000
        S[0]: 0
        S[1]: 1
        S[2]: 2
        S[3]: 3
        S[4]: 4
    [2] prob: 2.000000
        S[0]: 0
        S[1]: 2
        S[2]: 4
        S[3]: 6
        S[4]: 8
    [3] prob: 3.000000
        S[0]: 0
        S[1]: 3
        S[2]: 6
        S[3]: 9
        S[4]: 12
    [4] prob: 4.000000
        S[0]: 0
        S[1]: 4
        S[2]: 8
        S[3]: 12
        S[4]: 16
    [5] prob: 5.000000
        S[0]: 0
        S[1]: 5
        S[2]: 10
        S[3]: 15
        S[4]: 20
    [6] prob: 6.000000
        S[0]: 0
        S[1]: 6
        S[2]: 12
        S[3]: 18
        S[4]: 24
    [7] prob: 7.000000
        S[0]: 0
        S[1]: 7
        S[2]: 14
        S[3]: 21
        S[4]: 28
    [8] prob: 8.000000
        S[0]: 0
        S[1]: 8
        S[2]: 16
        S[3]: 24
        S[4]: 32
    [9] prob: 9.000000
        S[0]: 0
        S[1]: 9
        S[2]: 18
        S[3]: 27
        S[4]: 36