我對(duì)中軟的第三題關(guān)于“內(nèi)存”的題目感興趣,特拿來(lái)探討。題目如下:
三. 有關(guān)內(nèi)存的思考題
1. void getmemory(char *p)
{
p=(char*)malloc(100);
}
void test(void)
{
char * str =null;
getmemory(str);
strcpy(str, "hello,world");
printf(str);
}
請(qǐng)問(wèn)運(yùn)行Test函數(shù)會(huì)有什么樣的結(jié)果
2. char*getmemory(void)
{
char p[]="hello world";
return p;
}
void test(void)
{
char *str=null;
str=getmemory();
printf(str);
}
請(qǐng)問(wèn)運(yùn)行Test 函數(shù)會(huì)有什么樣的結(jié)果.
答案很簡(jiǎn)單,1 運(yùn)行過(guò)程中會(huì)出現(xiàn)錯(cuò)誤 2 會(huì)輸出 亂碼
題目看似不難,但程序員,尤其是初級(jí)的程序員在寫代碼時(shí)很容易犯的一個(gè)毛病。
C語(yǔ)言中,實(shí)參變量和形參變量之間的數(shù)據(jù)傳遞是單向的“值傳遞”方式,指針變量作函數(shù)參數(shù)也要遵循這一原則。調(diào)用函數(shù)不能改變實(shí)參指針變量的值(即指針的地址),但可以改變實(shí)參指針變量所指變量的值。
程序1就試圖改變 str 的值,肯定不成功,getmemory執(zhí)行完后,str還是NULL,所以在執(zhí)行strcpy時(shí),程序試圖給NULL的指針賦值,會(huì)發(fā)生運(yùn)行時(shí)錯(cuò)誤。
程序2的問(wèn)題在于 getmemory函數(shù)試圖返回局部變量的地址。眾所周知,局部變量的生命只存在于該函數(shù)體內(nèi),一旦離開(kāi)該函數(shù)體,該局部變量便在內(nèi)存中消失,所以str得到的只能是亂碼。當(dāng)然也不排除在某些特定的編譯器上會(huì)輸出“hello,world”字樣。但嚴(yán)格的按照標(biāo)準(zhǔn)C來(lái)說(shuō),這種寫法也是不被允許的。