2014-01-22 104 views
7

我有以下代碼:分配到陣列中的結構在C

typedef struct Test { 
    long mem[1000]; 
} Test; 

extern Test *test; 
int main() { 
    Test *test = (Test *)malloc(sizeof(Test)); 
    test->mem[0] = 1; 
    test->mem[1] = 2; 
    test->mem[2] = 3; 
    test->mem[3] = 4; 
    test->mem[4] = 5; 
    test->mem[5] = 6; 
    return 0; 
} 

它的工作好,但我想改變MEM陣列中的初始化是在這樣:

test->mem = {1,2,3,4,5,6}; 

但海灣合作委員會給我這個錯誤:

error: expected expression before '{' token test->mem = {1,2,3,4,5,6}; With arrow pointing to the left open braces.

它可能是什麼?

謝謝!

編輯: 我也試試這個代碼:

long mem[1000] = {1,2,3,4,5,6}; 
    test->mem = mem; 

而且我從GCC收到此錯誤:

error: incompatible types when assigning to type 'long int[1048576]' from type 'long int *' test->mem = mem;

我不允許使用任何C函數。

回答

10

語法something = { initial values }僅在初始化,其中一個對象被定義,如允許:

long mem[1000] = { 1, 2, 3, 4, 5, 6 }; 

的表達式如x = value分配並且不能使用用於初始化的語法。

一種替代方法是創建一個臨時對象,初始化,然後將該臨時對象的內容複製到目標:

static const long temporary[] = { 1, 2, 3, 4, 5, 6 }; 
memcpy(test->mem, temporary, sizeof temporary); 

關於編輯:

數組不得轉讓;如果x是數組,則x = value無效。然而,結構可以被分配,所以另一種選擇是創建一種結構作爲一個臨時對象,進行初始化,並指定:

// (After the malloc is successful.) 
static const Test temporary = { { 1, 2, 3, 4, 5, 6 } }; 
*test = temporary; 

但是請注意,此代碼執行一些現有代碼沒有。我之前展示的例子只是將六個元素複製到數組中。此代碼創建一個類型爲Test的臨時對象,其中包含1000個元素,其中大多數爲零,並將所有這些元素複製到*test。即使編譯器對此進行了優化,並使用一些代碼清除了*test,而不是實際上覆制存儲在內存中的零,但這需要比複製六個元素更長的時間。所以,如果你只是想要初始化一些元素而不關心其他元素,可以使用前面的代碼。如果您想要初始化所有元素(大多數爲零),則可以使用後面的代碼。 (即使這樣,我會考慮替代方案,如使用calloc而不是malloc。)

+0

請參閱問題中的編輯。 – Nir

2

數組不是指針(但陣列衰減到指針,看this)和不能分配陣列(僅初始化它們,或分配含有它們struct -s)。您可以複製陣列,例如

Test *test = (Test *)malloc(sizeof(Test)); 
if (!test) { perror("malloc"); exit(EXIT_FAILURE); }; 
static const int arr[] = {1,2,3,4,5,6}; 
memcpy (test->mem, arr, sizeof(arr)); 

順便說一句,你可以通過編碼你的循環for (int i=0; i<6; i++) test->mem[i] = arr[i]; ....

這使得在test初始化9994點的整數,而無需使用memcpy複印件;您可能需要清除它們:

memset (test->mem+6, 0, 9994*sizeof(int)); 

或使用其他for循環。

你也可以定義你的初始化結構,例如

Test mystruct = {0, 2, 4, 6, 8}; 

然後分配它,例如,但是你不能分配數組!即使

// wrong code, won't compile 
int ta[4] = { 0, 1, 2, 3}; // initialization, not assignment 
int tb[4] = { 2, 4, 6, 8}; // ditto 
int *tp = &ta; 
ta = tb; // wrong! 
tb = tp; // also wrong 

不會編譯。

FWIW,C++11std::array有幫助。

C11標準的§6.5.16.1簡單賦值部分(見第102頁​​草案)列出了一組關於轉讓限制,以及數組賦值不適合那裏。因此它被禁止。經驗法則是隻有標量(包括指針和數字l-values)或struct -s可以出現在賦值的左側(或者從函數開始是return -ed)。

+0

對不起,我不明白。爲什麼test-> mem [0] = 1;工作和測試 - > mem = {1,2,3,4,5,6};不? – Nir

+1

我不明白「陣列不是指針」這個陳述是如何相關的。問題中的代碼不會嘗試將指針用作數組,反之亦然。問題是嘗試使用初始化語法進行分配。 –

+1

@EricPostpischil我相信它與這個問題的最新編輯有關。 – ApproachingDarknessFish