c++ --> 返回值分析

返回值分析 

  函数不能通过返回指向栈内存的指针,返回指向堆内存的指针是可以的。

 

一、返回局部变量的值

可以有两种情况:返回局部自动变量和局部静态变量,比如:

int func()
{
    int temp = 0;   // 返回局部自动变量的值,没问题
    return temp;
}

局部变量temp存储在栈中,函数返回时会自动复制一份temp的copy给调用者,没有问题。

int func()
{
    static int a = 1;   // 返回局部静态变量的值,没问题
    return a;
} 

 局部变量a存储在静态(全局)存储区中仅分配一次内存,并且函数返回后,变量不会销毁,没有问题。

vector<int> func()
{
    vector<int> v;
    v.push_back(0);
    return v;         //返回v的值拷贝,没问题
}
Person func()
{
    Person p1;
    p1.name = "test";
    return p1;       //返回值拷贝,会调用person类的拷贝构造函数,没问题
}

  

二、返回局部变量的指针

int* func()
{
    int temp = 0;      //返回局部变量的地址
    return &temp;      //返回时讲已销毁的地址返回给调用者,结果不可预知
} 
int* func()
{
    static int temp = 1;
    return &temp;        //返回指向静态存储区变量的指针, 没问题
}
char* func()
{
    char *p = "test";
    return p;        //由于字符串test存储在常量存储区(不是静态存储区),返回一个指向常量的字符串指针是可行的。
}
char* func()
{
    char str[] = "test";
    return str;       //函数返回一个已销毁的局部变量是不可行的。解决办法就是将字符串str声明为static。
}
char* func()
{
    char *str = (char *)malloc(sizeof(char) * BUFFER_SIZE);
    strcpy(str, "test");
    return str;       //函数返回一个指向堆内存的指针,由于堆存储区由程序员手动管理,可行的,但是要防止出现内存泄露,函数调用完后需要手动释放内存。
}
 
char *temp = NULL;
temp = func();
// some operation...
free(temp); 

 三、返回局部变量的引用

int& func()
{
    int temp = 0;     //返回局部变量的引用
    return temp;      //返回的temp本身,但已销毁,结果不可预知
}
 

四、静态全局变量和全局变量的区别

静态全局变量只在当前文件中可用,全局变量在其他文件中也可用,需要用extern声明。全局变量和静态变量如果没有手动初始化,则默认由编译器初始化为0。

#include <stdio.h>   
char *returnStr()   
{   
    char *p="hello world!";    //hello world!"是一个字符串常量,存放在只读数据段,把该字符串常量存放的只读数据段的首地址赋值给了指针 
    return p;                 //返回没问题
}   
int main()   
{   
    char *str;   
    str=returnStr();   
    printf("%s
", str);   
    return 0;   
}
#include <stdio.h>   
char *returnStr()   
{   
    char p[]="hello world!";        //"hello world!"是局部变量存放在栈中。当returnStr函数退出时,栈要清空,局部变量的内存也被清空了 
    return p;    
}   
int main()   
{   
    char *str;   
    str=returnStr();   
    printf("%s
", str);       //打印可能是乱码
    return 0;   
}
int func()  
{  
      int a;  
      ....  
      return a;    //允许  
}                     
  
int * func()  
{  
      int a;  
      ....  
      return &a;    //无意义,不应该这样做  
}

由于a返回的是值,无论是自动还是静态,返回局部变量的值是没有问题的;返回指向局部变量的指针,在调用结束后局部自动变量被销毁,指针指向一个不存在的对象,返回无意义。

#include <stdio.h>   
char *returnStr()   
{   
    static char p[]="hello world!";            //如果非要返回一个局部变量的地址,那么该局部变量一定要申明为static类型
    return p;   
}   
int main()   
{   
    char *str;   
    str=returnStr();   
    printf("%s
", str);         
    return 0;   
}
char *GetMemory3(int num)  
{  
    char *p = (char *)malloc(sizeof(char) * num);  
    return p;                 //返回指向堆内存的指针是可以的 
}  
void Test3(void)  
{  
    char *str = NULL;  
    str = GetMemory3(100);  
    strcpy(str, "hello");  
    cout<< str << endl;  
    free(str);  
}
原文地址:https://www.cnblogs.com/jeakeven/p/4549054.html