//NO.1:程式首先申請一個char類型的指標str,並把str指向NULL(即str裡存的是NULL的地址,*str為NULL中的值為0),調用函數的過程中做了如下動作:1申請一個char 類型的指標p,2把str的內容copy到了p裡(這是參數傳遞過程中系統所做的),3為p指標申請了100個空間,4返回Test函數.最後程式把字串hello
world拷貝到str指向的記憶體空間裡.到這裡錯誤出現了!str的空間始終為NULL而並沒有實際的空間.深刻理解函數調用的第2步,將不難發現問題所在!
void GetMemory(char *p)
{
p = (char*)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
//請問運行Test函數後會是什麼樣的結果?
//NO.2:程式首先申請一個char類型的指標str,並把str指向NULL.調用函數的過程中做了如下動作:1申請一數組p[]並將其賦值為hello world(數組的空間大小為12),2返回數組名p付給str指標(即返回了數組的首地址).那麼這樣就可以列印出字串"hello world"了嗎?當然是不能的!因為在函數調用的時候漏掉了最後一步.也就是在第2步return數組名後,函數調用還要進行一步操作,也就是釋放記憶體空間.當一個函數被調用結束後它會釋放掉它裡面所有的變數所佔用的空間.所以數組空間被釋放掉了,也就是說str所指向的內容將不確定是什麼東西.
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
//NO.3:問題同NO.1,正確答案為可以列印出hello.但記憶體流失了!
void GetMemory(char **p, int num)
{
*p = (char*)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
//NO.4:申請空間,拷貝字串,釋放空間.前三步操作都沒有任何問題.到if語句裡的判斷條件開始出錯了,因為一個指標被釋放之後其內容並不是NULL,而是一個不確定的值.所以if語句永遠都不能被執行.這也是著名的"野"指標問題.所以我們在編寫程式釋放一個指標之後一定要人為的將指標付成NULL.這樣就會避免出現"野"指標的出現.有人說"野"指標很可怕,會帶來意想不到的錯誤.
void Test(void)
{
char *str = (char*)malloc(100);
strcpy(str, "hello");
free(str);
if (str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
void GetMemory1(char *p)
{
p = (char *)malloc(100);
}
void Test1(void)
{
char *str = NULL;
GetMemory1(str);
strcpy(str, "hello world");
printf(str);
}
//str一直是空,程式崩潰
char *GetMemory2(void)
{
char p[] = "hello world";
return p;
}
void Test2(void)
{
char *str = NULL;
str = GetMemory2();
printf(str);
}
char *GetMemory3(void)
{
return "hello world";
}
void Test3(void)
{
char *str = NULL;
str = GetMemory3();
printf(str);
}
//Test3 中列印hello world,因為返回常量區,而且並沒有被修改過。Test2中不一定能列印出hello world,因為指向的是棧。
void GetMemory4(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test4(void)
{
char *str = NULL;
GetMemory3(&str, 100);
strcpy(str, "hello");
printf(str);
}
//記憶體沒釋放
void Test5(void)
{
char *str = (char *) malloc(100);
strcpy(str, "hello");
free(str);
if(str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
//str為野指標,列印的結果不得而知
void Test6()
{
char *str=(char *)malloc(100);
strcpy(str, "hello");
str+=6;
free(str);
if(str!=NULL)
{
strcpy(str, "world");
printf(str);
}
}
//VC宣告失敗,運行錯誤
//NO.1:程式首先申請一個char類型的指標str,並把str指向NULL(即str裡存的是NULL的地址,*str為NULL中的值為0),調用函數的過程中做了如下動作:1申請一個char 類型的指標p,2把str的內容copy到了p裡(這是參數傳遞過程中系統所做的),3為p指標申請了100個空間,4返回Test函數.最後程式把字串hello
world拷貝到str指向的記憶體空間裡.到這裡錯誤出現了!str的空間始終為NULL而並沒有實際的空間.深刻理解函數調用的第2步,將不難發現問題所在!
void GetMemory(char *p)
{
p = (char*)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
//請問運行Test函數後會是什麼樣的結果?
//NO.2:程式首先申請一個char類型的指標str,並把str指向NULL.調用函數的過程中做了如下動作:1申請一數組p[]並將其賦值為hello world(數組的空間大小為12),2返回數組名p付給str指標(即返回了數組的首地址).那麼這樣就可以列印出字串"hello world"了嗎?當然是不能的!因為在函數調用的時候漏掉了最後一步.也就是在第2步return數組名後,函數調用還要進行一步操作,也就是釋放記憶體空間.當一個函數被調用結束後它會釋放掉它裡面所有的變數所佔用的空間.所以數組空間被釋放掉了,也就是說str所指向的內容將不確定是什麼東西.
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
//NO.3:問題同NO.1,正確答案為可以列印出hello.但記憶體流失了!
void GetMemory(char **p, int num)
{
*p = (char*)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
//NO.4:申請空間,拷貝字串,釋放空間.前三步操作都沒有任何問題.到if語句裡的判斷條件開始出錯了,因為一個指標被釋放之後其內容並不是NULL,而是一個不確定的值.所以if語句永遠都不能被執行.這也是著名的"野"指標問題.所以我們在編寫程式釋放一個指標之後一定要人為的將指標付成NULL.這樣就會避免出現"野"指標的出現.有人說"野"指標很可怕,會帶來意想不到的錯誤.
void Test(void)
{
char *str = (char*)malloc(100);
strcpy(str, "hello");
free(str);
if (str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
void GetMemory1(char *p)
{
p = (char *)malloc(100);
}
void Test1(void)
{
char *str = NULL;
GetMemory1(str);
strcpy(str, "hello world");
printf(str);
}
//str一直是空,程式崩潰
char *GetMemory2(void)
{
char p[] = "hello world";
return p;
}
void Test2(void)
{
char *str = NULL;
str = GetMemory2();
printf(str);
}
char *GetMemory3(void)
{
return "hello world";
}
void Test3(void)
{
char *str = NULL;
str = GetMemory3();
printf(str);
}
//Test3 中列印hello world,因為返回常量區,而且並沒有被修改過。Test2中不一定能列印出hello world,因為指向的是棧。
void GetMemory4(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test4(void)
{
char *str = NULL;
GetMemory3(&str, 100);
strcpy(str, "hello");
printf(str);
}
//記憶體沒釋放
void Test5(void)
{
char *str = (char *) malloc(100);
strcpy(str, "hello");
free(str);
if(str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
//str為野指標,列印的結果不得而知
void Test6()
{
char *str=(char *)malloc(100);
strcpy(str, "hello");
str+=6;
free(str);
if(str!=NULL)
{
strcpy(str, "world");
printf(str);
}
}
//VC宣告失敗,運行錯誤