void GetMemory1(char *p)
{
p = (char*)malloc(100);
}
void Test1(void)
{
char *str = NULL;
GetMemory(str);
//把str傳進去,str是一個指針
strcpy(str, "hello world");
printf(str);
}
char *GetMemory2(void)
{
char p[] = "hello world";
return p;
}
void Test2(void)
{
char *str = NULL;
str = GetMemory2();
printf(str);
}
void GetMemory3(char **p, int num)
{
*p = (char*)malloc(num);
}
void Test3(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
void GetMemory4(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test4(void)
{
char *str = NULL;
GetMemory4(&str, 100);
strcpy(str, "hello");
free(str);
str = NULL;
printf(str);
}
請問運行Test函數後會是什麼樣的結果?
NO.1:程序首先申請一個char類型的指針str,並把str指向NULL(即str裏存的是NULL的地址,*str爲NULL中的值爲0)。
把str傳進去,str是一個指針,p是str的一個副本;.把str的內容copy到了p裏;爲p指針申請了100個空間。
p的值改變,但是str的值並沒有改變。str的空間始終爲NULL而並沒有實際的空間,程序崩潰
認爲 GetMemory(char *p)中的 p“就是” GetMemory(str)中的str。但p“不是”str,它只是“等於”str
就象: int a = 100;
int b = a; // 現在b等於a
b = 500; // 現在能認爲a = 500
顯然不能認爲a = 500,因爲b只是等於a,但不是a!當b改變的時候,a並不會改變,b就不等於a了。因此,雖然p已經有new的內存,但str仍然是null
改法一:雙重指針
而雙重指針爲什麼就可以了呢:把str的地址傳進去 ,p是str地址的一個副本
p指向的值改變,也就是str的值改變。
改法二:返回值
char *GetMemory()
{
char *p=(char *)malloc(100);
return p;
}
void Test(void)
{
char *str=NULL;
str=GetMemory();
strcpy(str,"hello world");
printf(str);
}
NO.2: 程序首先申請一個char類型的指針str,並把str指向NULL.調用函數的過程中做:
1.申請一數組p[]並將其賦值爲hello world(數組的空間大小爲12),
2.返回數組名p付給str指針(即返回了數組的首地址).那麼這樣就可以打印出字符串"hello world"了麼?當然是不能的!當一個函數被調用結束後它會釋放掉它裏面所有的變量所佔用的空間.所以數組空間被釋放掉了,也就是說str所指向的內容將不確定是什麼東西.
其根源在於不理解變量的生存期;
NO.3:(1)能夠輸出hello (2)內存泄漏
NO.4: 申請空間,拷貝字符串,釋放空間.前三步操作都沒有任何問題.到if語句裏的判斷條件開始出錯了,因爲一個指針被釋放之後其內容並不是NULL,而是一個不確定的值.
應加上:str = NULL;
char *GetMemory5(void)
{
return "hello world";
}
void Test5(void)
{
char *str = NULL;
str = GetMemory3();
printf(str);
}
打印hello world,因爲返回常量區,而且並沒有被修改過
對內存操作的考查主要集中在:
(1)指針的理解;
(2)變量的生存期及作用範圍;
(3)良好的動態內存申請和釋放習慣。
swap( int* p1,int* p2 )
{
int *p;
*p = *p1;
*p1 = *p2;
*p2 = *p;
}
在swap函數中,p是一個“野”指針,有可能指向系統區,導致程序運行的崩潰。在VC++中DEBUG運行時提示錯誤“Access Violation”。該程序應該改爲:
swap( int* p1,int* p2 )
{
int p;
p = *p1;
*p1 = *p2;
*p2 = p;
}