先看一段容易犯錯的代碼段:
#include<iostream>
using namespace std;
char* GetMe()
{
char st[]="hello word!";
return st;
}
int main()
{
char *str;
str=GetMe();
cout<<str<<endl;
return 0;
}
該段代碼可能輸出正確結果,也可能輸出錯誤結果。原因是:GetMe函數中的str是局部變量,分配的是局部數組,他是在內存中的棧中申請的空間,超出該函數作用域之後st的內存空間就會被收回,雖然返回的指針仍然指向該內存空間,但是空間中的值隨時有可能會被改變,所以輸出的有可能是錯誤結果。修改的方法一種是在全局區域申請內存空間,一種是在堆中申請內存空間。先看在內存的全局區域申請內存空間的代碼,至於在堆區分配內存有關文章已經講了,不再贅述:
#include<iostream>
using namespace std;
const char* GetMe()
{
char *st="hello word!";
//*st='t';
return st;
}
int main()
{
const char *str;
str=GetMe();
cout<<str<<endl;
return 0;
}
char *st=“hello word!”與上一段代碼中的char st[]="hello word!"的區別是char *st=“hello word!”是在內存的全局區域申請的內存空間,全局區域的值是不能進行修改的。如代碼中被註釋起來的那一行,如果去掉註釋,雖然編譯時沒錯誤,但是運行時程序就會崩潰,因爲修改了全局區域的值。所以在全局區域定義了變量之後,該值在程序結束之前是不會被改變的。另外需要普及的常識就是:
程序用來存放數據 的內存分爲四塊:
1、全局區(靜態區):全局變量和靜態變量存儲的地方,它與其他變量的不同之處就是生命週期的不同,全局區的變量只有在程序結束時系統纔會釋放該塊資源。
2、文字常量區:常量字符串存放的地方。它也是在程序結束時釋放。
3、棧區:存放函數的參數值,局部變量值等,進入區域分配內存,超出區域收回內存。
4、堆區:程序員分配程序員釋放。
當然了該題目也可以通過開闢一段靜態內存區來實現,它與全局區是同一塊內存,只是代碼表示方式不同:
#include<iostream>
using namespace std;
const char* GetMe()
{
static char st[]="hello word!";
//*st='t';
return st;
}
int main()
{
const char *str;
str=GetMe();
cout<<str<<endl;
return 0;
}