2014-03-01 75 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