亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

我是否施放了malloc的結果?

我是否施放了malloc的結果?

達令說 2019-05-20 15:02:34
在這個問題,有人建議意見,我應該不會投的結果malloc,即int *sieve = malloc(sizeof(int) * length);而不是:int *sieve = (int *) malloc(sizeof(int) * length);為什么會這樣呢?
查看完整描述

7 回答

?
呼喚遠方

TA貢獻1856條經驗 獲得超11個贊

 ; 你沒有投射結果,因為:

  • 這是不必要的,因為void *在這種情況下自動且安全地提升到任何其他指針類型。

  • 它增加了代碼的混亂,轉換不是很容易閱讀(特別是如果指針類型很長)。

  • 它讓你重復自己,這通常很糟糕。

  • 如果您忘記包含,它可以隱藏錯誤<stdlib.h>。這可能會導致崩潰(或更糟的是,導致崩潰,直到方式在后面的代碼的一些完全不同的部分)。考慮如果指針和整數的大小不同會發生什么; 那么你通過強制轉換隱藏了一個警告,可能會丟失你返回的地址。注意:從C11開始,隱式函數從C中消失,并且這一點不再相關,因為沒有自動假設未聲明的函數返回int。

作為澄清,請注意我說“你不投”,而不是“你不需要投”。在我看來,即使你做對了也沒有包括演員。這樣做沒有任何好處,但是一堆潛在的風險,包括演員表明你不知道風險。

還要注意,正如評論員指出的那樣,上面談的是直C,而不是C ++。我非常堅信C和C ++是不同的語言。

要進一步添加,您的代碼會不必要地重復int可能導致錯誤的類型信息()。最好取消引用用于存儲返回值的指針,將兩者“鎖定”在一起:

int *sieve = malloc(length * sizeof *sieve);

這也會移動length到前面以增加可見性,并刪除多余的括號sizeof只有在參數是類型名稱時才需要它們。許多人似乎不知道(或忽略)這一點,這使得他們的代碼更加冗長。記?。?code>sizeof不是功能!:)


雖然移動length到前面可能會增加在某些極少數情況下的可見性,但是在一般情況下,應該注意將表達式編寫為:

int *sieve = malloc(sizeof *sieve * length);

因為sizeof在這種情況下保持第一個,所以確保乘法至少用size_t數學來完成。

比較:malloc(sizeof *sieve * length * width)malloc(length * width * sizeof *sieve)第二個可能溢出的length * width時間widthlength比較小的類型size_t


查看完整回答
反對 回復 2019-05-20
?
MMTTMM

TA貢獻1869條經驗 獲得超4個贊

在C中,您不需要轉換返回值malloc。返回的void指針malloc自動轉換為正確的類型。但是,如果您希望使用C ++編譯器編譯代碼,則需要進行強制轉換。社區中的首選替代方案是使用以下內容:

int *sieve = malloc(sizeof *sieve * length);

如果你改變了類型,你還可以免去擔心改變表達式的右側sieve。

人們已經指出,演員陣容很糟糕。特別是指針轉換。


查看完整回答
反對 回復 2019-05-20
?
牛魔王的故事

TA貢獻1830條經驗 獲得超3個贊

演員,因為:

  • 它使您的代碼在C和C ++之間更具可移植性,并且正如SO經驗所示,許多程序員聲稱他們在用C ++(或C加本地編譯器擴展)編寫時正在用C語言編寫。

  • 如果不這樣做可以隱藏錯誤:注意所有的混亂的SO例子,當寫type *type **

  • 它讓你不會注意到你沒有找到#include合適的頭文件的想法錯過了森林的樹木。這就像說“不要擔心你沒有要求編譯器抱怨沒有看到原型這一事實 - 那令人討厭的stdlib.h是真正重要的事情要記住!”

  • 它強制進行額外的認知交叉檢查。它將(聲稱的)所需類型放在您正在為該變量的原始大小進行的算術旁邊。我敢打賭你可以做一個SO研究,它表明malloc()當有一個演員時,bug會被抓得更快。與斷言一樣,顯示意圖的注釋可以減少錯誤。

  • 以機器可以檢查的方式重復自己通常是一個主意。事實上,這就是一個斷言,并且使用強制轉換是一種斷言。斷言仍然是我們獲得正確代碼的最常用技術,因為圖靈在很多年前提出了這個想法。


查看完整回答
反對 回復 2019-05-20
?
呼啦一陣風

TA貢獻1802條經驗 獲得超6個贊

正如其他人所說,C不是必需的,而是C ++。如果您認為要使用C ++編譯器編譯C代碼,出于某種原因,您可以使用宏,例如:

#ifdef __cplusplus# define NEW(type, count) ((type *)calloc(count, sizeof(type)))#else# define NEW(type, count) 
(calloc(count, sizeof(type)))#endif

這樣你仍然可以以非常緊湊的方式編寫它:

int *sieve = NEW(int, 1);

它將為C和C ++編譯。


查看完整回答
反對 回復 2019-05-20
?
蝴蝶刀刀

TA貢獻1801條經驗 獲得超8個贊

在C中,您可以隱式地將void指針轉換為任何其他類型的指針,因此不需要強制轉換。使用一個人可能會向不經意的觀察者建議,有一些理由需要一個,這可能會產生誤導。


查看完整回答
反對 回復 2019-05-20
?
收到一只叮咚

TA貢獻1821條經驗 獲得超5個贊

你沒有強制轉換malloc的結果,因為這樣做會給你的代碼帶來無意義的混亂。

人們投射malloc結果的最常見原因是因為他們不確定C語言是如何工作的。這是一個警告信號:如果您不知道特定語言機制的工作原理,那么請不要猜測。查找或詢問Stack Overflow。

一些評論:

  • 可以將void指針轉換為/從任何其他指針類型轉換而不進行顯式轉換(C11 6.3.2.3和6.5.16.1)。

  • 但是,C ++不允許在void*另一個指針類型之間進行隱式轉換。所以在C ++中,演員陣容是正確的。但是如果你用C ++編程,你應該使用new而不是malloc()。而且你永遠不應該使用C ++編譯器編譯C代碼。

    如果需要使用相同的源代碼同時支持C和C ++,請使用編譯器開關來標記差異。不要嘗試使用相同的代碼來區分兩種語言標準,因為它們不兼容。

  • 如果C編譯器由于忘記包含頭而無法找到函數,那么您將收到編譯器/鏈接器錯誤。因此,如果您忘記包含<stdlib.h>那些沒什么大不了的話,那么您將無法構建您的程序。

  • 對于遵循超過25年的標準版本的古代編譯器,忘記包含<stdlib.h>將導致危險的行為。因為在那個古老的標準中,沒有可見原型的函數隱式地將返回類型轉換為int。然后顯式地從malloc轉換結果將隱藏此錯誤。

    但這確實不是問題。您沒有使用25年的計算機,那么為什么要使用25年的編譯器呢?


查看完整回答
反對 回復 2019-05-20
  • 7 回答
  • 0 關注
  • 651 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號