1. 程式人生 > >C++函數返回局部變量

C++函數返回局部變量

接口 blog 數組名 結束 要求 地址 比較 一個 cde

函數不能返回指向棧內存的指針

原因:返回值是拷貝值,局部變量的作用域為函數內部,函數執行結束,棧上的局部變量會銷毀,內存釋放。

可返回的局部變量:

1. 返回局部變量本身

技術分享
int sum(int a, int b)
{
    int s=a+b;
    return s;
}
View Code

2.常量:

char* returnValue()  
{  
    char* str="HelloJacky";  
    return str;  
}  

char * str=“hello world”字符串常量,不能str[1]=‘a‘. 常量不能修改。 這種語法是為了兼容c代碼。“hello world” 是const char * 類型。然後將char * 指向存儲的位置。使用C++編譯器會有警告提示:

warning: deprecated conversion from string constant to ‘char*‘ [-Wwrite-strings]|
推薦把類型修改為const char *
也就是說,這種語法的存在,只是為了保證以前的C代碼可以正常編譯。
//錯誤
char* returnValue()  
{  
    char str[]="HelloJacky";  
    return str;  
}  

str 為局部變量

3. 靜態局部變量

當多次調用一個函數且要求在調用之間保留某些變量的值時,可考慮采用靜態局部變量。雖然用全局變量也可以達到上述目的,但全局變量有時會造成意外的副作用,因此仍以采用局部靜態變量為宜。

//正確
char
* returnValue() { static char str[]="HelloJacky"; return str; }

強制定義為靜態類型;

int* returnValue()  
{  
    static int value[3]={1,2,3};  
    return value;  
}  

數組名是不就變量的首地址,加上static 可以

4. 堆內存中的局部變量

//正確
int
*sum(int a, int b) { int *s=new int(); *s=a+b; return
s; }
char* newMemory(int size)  
{  
    char* p=NULL;  
    p=new char[size];  
    return p;  
}  

int _tmain(int argc, _TCHAR* argv[])  
{  
    char* p=newMemory(2);  
    if(p!=NULL)  
    {  
        *p=a;  
    }  
    std::cout<<*p;  
    delete [] p;  
    return 0;  
}  

在函數內new空間,在函數外delete空間。函數內申請空間,調用後釋放空間。但這不是一種好的編程習慣,盡量在同一作用域內進行new和 delete操作。接口不靈活

五大內存分區(貌似與編譯原理中不一樣,不過道理是一樣的,實際存在的東西總是會與理論有一定差距的)
1.在C++中,內存分成5個區,他們分別是堆、棧、自由存儲區、全局/靜態存儲區和常量存儲區。
2.棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清楚的變量的存儲區。裏面的變量通常是局部變量、函數參數等。
3.堆,就是那些由new分配的內存塊,他們的釋放編譯器不去管,由我們的應用程序去控制,一般一個new就要對應一個delete。如果程序員沒有釋放掉,那麽在程序結束後,操作系統會自動回收。
4.自由存儲區,就是那些由malloc等分配的內存塊,他和堆是十分相似的,不過它是用free來結束自己的生命的。
5.全局/靜態存儲區,全局變量和靜態變量被分配到同一塊內存中,在以前的C語言中,全局變量又分為初始化的和未初始化的,在C++裏面沒有這個區分了,他們共同占用同一塊內存區。
6.常量存儲區,這是一塊比較特殊的存儲區,他們裏面存放的是常量,不允許修改(當然,你要通過非正當手段也可以修改,而且方法很多)

C++函數返回局部變量