假設「structName」是定義的結構:這段代碼真的在做什麼?
structName ** sarray = (structName **) malloc(0 * sizeof(structName *));
我知道它創建一個指向名爲sarray一個結構指針,但爲什麼會有放置在表達式的開始(structName **)?另外,爲什麼malloc調用中的struct size乘以0?
代碼的源是here
假設「structName」是定義的結構:這段代碼真的在做什麼?
structName ** sarray = (structName **) malloc(0 * sizeof(structName *));
我知道它創建一個指向名爲sarray一個結構指針,但爲什麼會有放置在表達式的開始(structName **)?另外,爲什麼malloc調用中的struct size乘以0?
代碼的源是here
malloc
返回void *
。指針sarray
的類型爲structName **
。 (structName **)
是一種類型轉換,將void *
轉換爲structName **
。指針在C中非常可塑; malloc
將始終返回可以安全地投射到任何種類的指針的東西。在這種情況下,您有一個指向structName *
的指針。
乘以sizeof(structName *)
由0
做你的想法,要求malloc
一個零長度的內存塊。我懷疑sizeof
在那裏,因爲作者認爲它是標準模式。你可以刪除它,沒有任何後果,只是提供0.鑑於realloc
與NULL
參數一起使用,你也可以只是初始化sarray
到NULL
。
對於記錄,爲malloc
:
如果所請求的空間的大小是零,則該行爲定義 implementation-:返回任一個空指針,或 行爲是因爲如果大小是非零值,但不應使用返回的指針訪問對象。
因此,初始調用可能返回或不返回NULL
,結果基本相同:通過指針訪問任何內容應該有未定義的結果。
謝謝。我現在明白了。 – AJPennster 2014-10-07 00:29:27
malloc函數返回類型爲(void *)的指針。 (structName **)將該指針轉換爲類型(structName **)。這種轉換在C. 中不是必需的,他乘以0,因爲他不想分配任何結構,並且稍後等待重新分配。
爲什麼
(structName **)
放置在表達式的開頭?
它被稱爲type casting。 malloc
returns a void *
這是鑄造到structName **
,以便它可以被分配到sarray
。
此外,malloc調用中爲什麼struct size乘以0?
編碼模式malloc(size * sizeof(datatype))
通常隨處可見,因此在那裏使用乘法IMO。
structName ** sarray = (structName **) malloc(0 * sizeof(structName *));
等同於:
structName ** sarray = NULL;
的原因(structName **)
是的malloc()
返回值從void *
轉換爲(structName **)
,所以分配給sarray
不會產生不兼容的類型錯誤。
原因被零乘法與下面的語句兼容性:
long sarray_len = 0;
如果例如選擇了先從
long sarray_len = initialCount;
代替,那麼malloc
必須是
structName ** sarray = (structName **) malloc(initialCount * sizeof(structName *));
。
(structName **)
之前malloc
是一個錯誤。它是在20世紀70年代需要的,但自1989年以來一直是一個錯誤。許多人沒有更新自1989年以來的學習材料;-)
充其量是多餘的文本(通常應避免多餘的文本,因爲它使難以閱讀的重要文本),最糟糕的是它可以隱藏一個錯誤。有關該主題的進一步閱讀see this thread。
關於第二部分,0 * sizeof(structName *)
。這當然是0
,你可能會問爲什麼這個人不寫0
。
原因是該人符合使用malloc的特定風格。符合模式是最小化錯誤的一種方式。如果您經常閱讀本網站,您將會知道,錯誤地使用malloc是人們無法追查的最常見錯誤之一。所使用的模式爲:
T *ptr = (T *) malloc(number_of_elements * sizeof(T));
其中分配一定數目的T
類型的元素的陣列。即使數字爲0
(但對於負數不合法),這也是合法的。在這種情況下,它可以返回一個空指針或一個非空指針。無論哪種情況,當然你都不能嘗試訪問任何數組元素。
這種模式很常見,但正如鏈接線程中提到的那樣,存在問題,並且自1989年以來存在更好的選擇。
注意:考慮使用calloc
分配內存。由於兩個數字之間用逗號分隔,而不是乘法運算符,所以稍微清晰一些,在某些操作系統(例如Linux)上,它的執行速度可能快於malloc
。
我的猜測是'0'是一個硬編碼的幻數,而你的前任曾經把它作爲一個非零值。 '(structName **)'是一個類型轉換。編輯:它看起來像數組應該增長使用'realloc',但開始爲'0'大小。 'sizeof(structName *)'可能只是包含在內,因爲它的良好實踐。 – acbabis 2014-10-06 23:32:07
代碼開始爲將根據需要展開的數組分配一個零大小的塊(或試圖分配一個塊)。這是有效的,但是任何做這種事情的人都需要小心 - malloc()被指定爲可以將NULL或地址返回到零大小的內存塊。在示例代碼的情況下,這是可以的,因爲在擴展零大小的塊或NULL指針時,realloc()將表現良好。 – 2014-10-06 23:34:50
問:這行代碼真的在做什麼?簡答:沒有用。較長的回答:1)我推遲'malloc()',直到我有一個非零值分配,2)我一般喜歡形式'malloc(sizeof結構名);',而不是指針指針**)。 – FoggyDay 2014-10-06 23:42:15