轉自:https://www.cnblogs.com/fanhaha/p/7117766.html
原因:返回值是拷貝值,局部變量的作用域為函數內部,函數執行結束,棧上的局部變量會銷毀,內存釋放。
可返回的局部變量:
1. 返回局部變量本身
1 int sum(int a, int b) 2 { 3 int s=a+b; 4 return s; 5 }
2.常量:
1 char* returnValue() 2 { 3 char* str="HelloJacky"; 4 return str; 5 }
char * str=“hello world”字符串常量,不能str[1]='a'. 常量不能修改。 這種語法是為了兼容c代碼。“hello world” 是const char * 類型。然后將char * 指向存儲的位置。使用C++編譯器會有警告提示:
推薦把類型修改為const char *
也就是說,這種語法的存在,只是為了保證以前的C代碼可以正常編譯。
1 //錯誤 2 char* returnValue() 3 { 4 char str[]="HelloJacky"; 5 return str; 6 }
str 為局部變量
3. 靜態局部變量
當多次調用一個函數且要求在調用之間保留某些變量的值時,可考慮采用靜態局部變量。雖然用全局變量也可以達到上述目的,但全局變量有時會造成意外的副作用,因此仍以采用局部靜態變量為宜。
1 //正確 2 char* returnValue() 3 { 4 static char str[]="HelloJacky"; 5 return str; 6 }
強制定義為靜態類型;
1 int* returnValue() 2 { 3 static int value[3]={1,2,3}; 4 return value; 5 }
數組名是不就變量的首地址,加上static 可以
4. 堆內存中的局部變量
1 //正確 2 int *sum(int a, int b) 3 { 4 int *s=new int(); 5 *s=a+b; 6 return s; 7 }
1 char* newMemory(int size) 2 { 3 char* p=NULL; 4 p=new char[size]; 5 return p; 6 } 7 8 int _tmain(int argc, _TCHAR* argv[]) 9 { 10 char* p=newMemory(2); 11 if(p!=NULL) 12 { 13 *p='a'; 14 } 15 std::cout<<*p; 16 delete [] p; 17 return 0; 18 }
在函數內new空間,在函數外delete空間。函數內申請空間,調用后釋放空間。但這不是一種好的編程習慣,盡量在同一作用域內進行new和 delete操作。接口不靈活
五大內存分區(貌似與編譯原理中不一樣,不過道理是一樣的,實際存在的東西總是會與理論有一定差距的)
1.在C++中,內存分成5個區,他們分別是堆、棧、自由存儲區、全局/靜態存儲區和常量存儲區。
2.棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清楚的變量的存儲區。里面的變量通常是局部變量、函數參數等。
3.堆,就是那些由new分配的內存塊,他們的釋放編譯器不去管,由我們的應用程序去控制,一般一個new就要對應一個delete。如果程序員沒有釋放掉,那么在程序結束后,操作系統會自動回收。
4.自由存儲區,就是那些由malloc等分配的內存塊,他和堆是十分相似的,不過它是用free來結束自己的生命的。
5.全局/靜態存儲區,全局變量和靜態變量被分配到同一塊內存中,在以前的C語言中,全局變量又分為初始化的和未初始化的,在C++里面沒有這個區分了,他們共同占用同一塊內存區。
6.常量存儲區,這是一塊比較特殊的存儲區,他們里面存放的是常量,不允許修改(當然,你要通過非正當手段也可以修改,而且方法很多)