2013-03-01 87 views
1

當我寫下面的代碼,我得到奇怪的答案。不能理解爲什麼c中的malloc函數做如下解釋?

#include<stdio.h> 
#include<stdlib.h> 
main() 
{ 
int *p=malloc(1); 
if(p==0) 
printf("memory not assigned\n"); 
else 
{ 
printf("memory assigned\n"); 
printf("enter an int\t"); 
scanf("%d",p); 
printf("\n You entered number %d",*p); 
printf("\nIt has been stored at-%p",p); 
} 
} 

我覺得malloc的參數需要作爲byte.so這裏我輸入的1個字節數和我知道,我的機器上INT需要存儲4個字節(通過的sizeof()),但仍代碼顯示沒有錯誤,我可以輸入一個int value.even如果我輸入3333333它不會抱怨。如果我使用malloc()而不是malloc(1)gcc抱怨malloc的參數太少,但仍然給出相同的結果。我無法理解此行爲。有人請澄清一下。

我正在gcc上運行它通過虛擬框。

+1

「gcc抱怨malloc的參數太少,但仍然給出相同的結果」 - 由於編譯失敗,您的可執行文件沒有被覆蓋,爲什麼它會執行其他任何操作? – 2013-03-01 05:46:48

+0

當我再次運行它並輸入新值時,它很高興地採取了它並沒有抱怨。所以我不認爲以前的可執行文件沒有被覆蓋。 – 2013-03-01 06:17:31

+0

刪除可執行文件並重試。 – congusbongus 2013-03-01 06:57:49

回答

3

正如你所說,如果你這樣做:

int *p=malloc(1); 

只有1個字節將被分配。由於int大於1個字節,它會溢出分配的內存並給你未定義的行爲。如果你這樣做:

int *p=malloc(sizeof(int)); 

然後將有足夠的空間的整數。

當您在界限分配的內存之外運行時,C不會警告您,因此您需要仔細管理您的malloc大小。

+0

我同意you.but當我做一些像int * p = malloc(),這裏我給malloc沒有參數,我不指定任何字節我需要。因此,編譯器應該打印內存不assigned.is它?或編譯器以其他方式解決這個問題。 – 2013-03-01 06:05:15

+0

有些編譯器可能會替換默認參數 - 它會是'int malloc();',並且這將與malloc的實現鏈接時,行爲將是未定義的。 Malloc預計會有一個整數,這可能是零,但也可能是其他任何東西。一些編譯器,比如gcc 4.6.1。會給函數malloc帶來錯誤'''''' – 2013-03-01 07:29:07

0

未定義的行爲? malloc(1)返回空閒塊或大小爲1個字節,除了返回的塊之外可能會有更多的塊,其中您的整數將被寫入(即韻!)

很明顯,malloc()需要1個參數。如果你沒有提供,gcc 抱怨,所有符合C標準的其他編譯器也是如此。

如果你想sizeof(int)字節,則:malloc(sizeof(int))

+0

是的,我明白海灣合作委員會應該抱怨。但我想說的是,爲什麼它允許代碼運行,儘管它有問題。 – 2013-03-01 05:53:59

+0

@THEPARADOX,因爲在C標準中沒有提到這種代碼不應該被允許。這一切都歸結爲C標準。編譯器必須遵守它 - 不管是什麼,沒有破壞過去的代碼 – 2013-03-01 05:55:36

+0

如果我寫int * p = malloc(),這裏我給malloc沒有參數,我沒有指定我需要的字節數。所以編譯器應該打印內存不分配,是嗎? – 2013-03-01 06:13:54

0

這是你的責任的Alloc足夠的內存滿足您的需求。編譯器不會檢查您是否正在訪問您分配的內存以外的內存。

如果您分配x內存量,要存儲大小大於x的值,您的應用程序可能(可能不會)在運行時崩潰。這是未定義的行爲。

如果你打電話malloc(1),沒有必要編譯器,因爲抱怨,malloc的需要一個參數(內存大小),而你通過它..

可是,當你調用malloc(),案件不同,編譯器抱怨..

0

malloc的執行不太可能給你一個字節。它的尺寸可能會達到最接近的字數,這意味着sizeof(int)將適合該空間。就像:

struct foo { 
    char a; 
}; 

sizeof(struct foo)將可能是字的大小。不用說,您應該分配更多空間(例如malloc(sizeof(int))),因爲您想要閱讀int。儘管事實上它「發生」工作,但對於後來的軟件維護來說,它會更容易混淆。這可能是未定義的行爲。