2014-03-01 69 views
2

我对C有点精通,我认为我有指针都想通了,直到我遇到了这个问题。我正在创建一个数组实现的结构体堆栈。很简单,但当我的结构包含一个动态分配的数组时,我遇到了一个问题。每个包含动态数组的结构数组

的结构是:

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); 

,我能创造一个struct在第一槽去:

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; 

但是,当我尝试添加第二个结构,赛格故障。这是因为数组索引的方式是没有int数组的结构体的大小,这意味着每个条目的长度为16个字节 - 8个为指针的双8个。我希望它可以通过28-8的双精度和4×5精度进行索引。有没有人知道一种方法来正确访问此数组的元素?

谢谢!

+0

你是否检查'root's件的内容,您assigend值后他们?尤其要检查'prob'的值! – alk

回答

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 *

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))和实际得到一个连续的内存块中在结构和排列在一起。但是,如果你这样做,你不能正确地设置一个state_t的数组,因为编译器不知道一个结构在哪里结束而另一个开始。

1

使用

  1. Arrays of Length Zero和它的GCC扩展
  2. 适当的类型转换
  3. 正确的指针运算

你可以得到你想要的东西,或多或少。

这里是我的测试程序(与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