malloc出錯?

#include &

#define BUFSIZER1 512

#define BUFSIZER2 ((BUFSIZER1/2))

main()

{

char *buf1R1;

char *buf2R1;

char *buf2R2;

char *buf3R2;

buf1R1 = (char *)malloc(BUFSIZER1);

buf2R1 = (char *)malloc(BUFSIZER1);

buf2R1 = NULL;

buf2R2 = (char *)malloc(BUFSIZER1);

}

不清楚為什麼一運行到這段就出錯,「buf2R2 = (char *)malloc(BUFSIZER1);」

我的同學機子上沒有出錯?

我的機子是Win10 64位;


復現題主問題的關鍵是使用C編譯器以及目標為64位程序。

其實這個問題通過仔細觀察warning就可以找到原因。

如@Belleve 所說,malloc函數的聲明可以通過包含stdlib.h找到。

如果未包含stdlib.h文件malloc實際上是未聲明的函數。

在C99之前未聲明函數默認返回值類型為int。如果鏈接到了不兼容類型的函數,運行時是未定義行為。

warning中提到將int轉換為char*,這一步VC的實現是帶符號擴展(cdqe)。

問題就出在這一步。實際的malloc函數返回的是一個64位指針,但編譯器認為它是一個32位的int,在轉成char*時做了帶符號擴展。

比如說malloc返回了0x0000028CC786F7C0,經過CDQE就變成了0xFFFFFFFFC786F7C0。

這樣就出現了一個野指針,不管是使用還是free都會出C0000005。解決方法就是包含stdlib.h,引入正確的malloc函數聲明。


#include &

(其實我不加也是正常運行的……)


你沒引用stdlib.h, 這點已經很多人提及了.

我想說的是, c-faq裡面提及了, 不要對你的malloc做強制類型轉換, 看下面的鏈接 (實際上我建議每個剛開始學c的孩子都看幾遍c-faq)

Question 7.7b

buf1R1 = (char *)malloc(BUFSIZER1);

改成

buf1R1 = malloc(BUFSIZER1);

雖然這麼做不會讓你的程序編譯成功, 但是避免了掩蓋編譯器警告.


可以肯定的是如果調用的cpp編譯器,那麼是肯定不能通過編譯的,會報error,malloc未定義。即便是引入stdlib.h依然會報錯,不能將void *轉成char *。 至少你這個程序在Linux C 下面肯定不能報錯的。


感覺是進程被注入了,然後注入的代碼自己有bug把heap寫壞了。


所以我強烈建議warning也是要檢查的。

別信老舊的教材上面的warning不用管,坑死你喲


按照提問文字所示代碼是不會出錯的,而按照提問配圖所示代碼才會出錯,原因正如@Felix Qiu所說。建議題主修改一下,以免引起廣大隻看文字不看圖片的童鞋懷疑人生啊。


#include &


把這個窗口打開, 看你載入的模塊


malloc函數被封裝在頭文件stdlib.h裡面,你不載入頭文件,編譯器識別不了malloc。而程序報錯在第18行,是出於編譯器的問題回溯機制。


buf2R1你申請了一段內存空間,這個指針本來指向這片空間,然後你沒有釋放,就把這個指針指向 NULL,這……指向NULL之前加個free試試?


推薦閱讀:

為什麼不建議用 try catch?
如果BUG和電腦病毒入侵到現實世界裡,TA們會長什麼樣?
如何正確高效的查找遊戲「卡頓」原因?
自學編程最大困難是什麼?

TAG:編程 | C編程語言 |