C++里面说函数的返回值不可以返回指向局部变量的指针。这个是绝对的么?

时间:2021-03-30 13:39:31
求大神看看。并分析下。我写了一个这样的函数。
C++里面说函数的返回值不可以返回指向局部变量的指针。这个是绝对的么?
char* getStr( char* str  )
{
    char* p=0;
    p=str ;
    
    return p; 

}
p是个局部变量,随着函数调用结束,它会直接销毁,如果指针已经销毁了,那么它指向的内存还在不在?我在oc里面直接调用,
   char* str=getStr("hello");
    NSLog(@"%s",str);
得到了返回值,难道这个规则跟编译器有关么?

23 个解决方案

#1


C++里面说函数的返回值不可以返回指向局部变量的指针。这个是绝对的么?C++里面说函数的返回值不可以返回指向局部变量的指针。这个是绝对的么?

#2


你给的例子不是指向局部变量的指针

#3


char* p=0;
    p=str ;//  str  并不是 局部变量 , 而 是 输入 参数。

#4


char* str=getStr("hello"); //这个 hello是局部变量? 明明是常量字符串 在全局变量数据区  不是在栈中

#5


不是不可以返回。返回的只不过是个野指针而已,只要你不怕内存崩掉。
你给的例子跟标题没半毛钱关系。

#6


C++里面说函数的返回值不可以返回指向局部变量的指针  ----- 实际就是指向变量A的指针,是看A的生存期,也就是说函数返回后,A是否还在生存期

#7


1. 这个函数返回的并不是局部变量的指针,而是调用这个函数时实参表达式的指针,LZ的例子与标题不是一回事

2.函数可以返回“static 局部变量”的指针,可以返回本函数调用malloc( )函数得到的指针

#8


WinSock中的常用函数

char *inet_ntoa(); 这就是一个返回局部变量的例子。有两点需要注意

1、返回的是局部变量,但是是静态的

2、使用了tls

#9


我说的局部变量指的是p哦,那个指针。指针本身就是一个变量,只不过它存的是另一个变量的地址而已。和输入参数无关,我也可以换一参数去调用。不一定getStr("hello")这样去调用。   如下。还是可以得到hello。这个arr总不是在全局变量数据区了吧
char arr[6]={'h','e','l','l','o'};
    char* str=getStr(arr);
    NSLog(@"%s",str);

#10


感谢各位的回答,还是有点不明白,要是哪位大神能写个demo,分析下就再好不过了。

#11


那再来看一个吧。
int* test(int b)
{
    int a=0;//局部变量
    a=b; //行参复制给a
    int * p=&a ; //定义一个int* 的指针,把变量a的地址给p
  
    return p; //返回p。这个p是不是局部变量的指针?我觉得是的

}

 int * result=test(5);
    
    NSLog(@"%d",*result); 
输出结果还是5.我分析的对么?

#12


引用 9 楼 u012186949 的回复:
我说的局部变量指的是p哦,那个指针。指针本身就是一个变量,只不过它存的是另一个变量的地址而已。和输入参数无关,我也可以换一参数去调用。不一定getStr("hello")这样去调用。   如下。还是可以得到hello。这个arr总不是在全局变量数据区了吧
char arr[6]={'h','e','l','l','o'};
    char* str=getStr(arr);
    NSLog(@"%s",str);


1.“我说的局部变量指的是p哦,那个指针”,那返回就应该是&p,但与该函数的返回值类型不符,正确的应该是char **

2.char arr[6]={'h','e','l','l','o'};
    char* str=getStr(arr);
arr是指向‘h'的指针----(数组名在许多场合是首元素的指针),即arr实际是&arr[0]
调用时传递给形参str,即str=&arr[0]
函数中:
 p=str

p=&arr[0]
返回p,返回p 即返回p的内容&arr[0],这不是局部变量p的指针,而是实参表达式的指针&arr[0].而你的arr[ ]不是这个被调函数的局部变量,而是主调函数提供的

#13



int * FunRetRef()
{
    int a = 0;

    cin>>a;

    printf("FunRetRef Get inputFromUsr == %d\n", a);

    return &a;
}

void TheThirdFunc( int nVal)
{
    int i = 0;
    int arr[10] = {0};

    for ( int i = 0; i < 10; i++ )
    {
        arr[i] = i * nVal;
    }

    for (int i = 0; i < 10; i++)
    {
        cout<<arr[i]<<" ";
    }

    cout<<endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    int *pRet = FunRetRef();
    cout<<"nRet Value == "<<*pRet<<endl;

    TheThirdFunc(argc);

    cout<<"nRet Value == "<<*pRet<<endl;

    return 0;
}


我闲的蛋疼。。 楼主自己调试看看吧。

#14


引用 13 楼 TheNewIpad 的回复:

int * FunRetRef()
{
    int a = 0;

    cin>>a;

    printf("FunRetRef Get inputFromUsr == %d\n", a);

    return &a;
}

void TheThirdFunc( int nVal)
{
    int i = 0;
    int arr[10] = {0};

    for ( int i = 0; i < 10; i++ )
    {
        arr[i] = i * nVal;
    }

    for (int i = 0; i < 10; i++)
    {
        cout<<arr[i]<<" ";
    }

    cout<<endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    int *pRet = FunRetRef();
    cout<<"nRet Value == "<<*pRet<<endl;

    TheThirdFunc(argc);

    cout<<"nRet Value == "<<*pRet<<endl;

    return 0;
}


我闲的蛋疼。。 楼主自己调试看看吧。
感谢大神。我会好好研究一下。

#15


返回的指向局部变量的指针是指向了一个已经被标记为“未使用”的内存,当然如果那个内存存的值是5的话系统也不会去清除这块内存的值,如果你打印这个内存的值 就会出现不确定因素因为 不知道什么时候内存值就会被改变。

#16


你返回的是指向局部变量的指针吗?显然不是啊

#17


引用 11 楼 u012186949 的回复:
那再来看一个吧。
int* test(int b)
{
    int a=0;//局部变量
    a=b; //行参复制给a
    int * p=&a ; //定义一个int* 的指针,把变量a的地址给p
  
    return p; //返回p。这个p是不是局部变量的指针?我觉得是的

}

 int * result=test(5);
    
    NSLog(@"%d",*result); 
输出结果还是5.我分析的对么?


这个p是局部变量的指针,返回的result里面 目前是5,因为result指向的内存(在栈上)目前没有被破坏,因为没有其他函数调用
你可以这样

int* test(int b)
{
int a=0;//局部变量
a=b; //行参复制给a
int * p=&a ; //定义一个int* 的指针,把变量a的地址给p

return p; //返回p。这个p是不是局部变量的指针?我觉得是的

}
void test2()
{
int a[10];
for (int i = 0; i < 10; i++)
{
a[i] = i;
}
}

int *result=test(5);
printf("%d\n", *result); //此时是5
test2();
printf("%d\n", *result); //此时是一个错误的值

#18


不可以返回指向局部非静态对象的指针 

顺便不是绝对的 
只是返回了不可以使用 没什么意义罢了

#19


能返回,你敢用么?

#20



// 哈哈,看你下次还敢返回局部变量的地址(指针)吗?
int *GetAddress()
{
    int x = 10;
    return &x;
}

int **GetAddress()
{
    int v = 10;
    int * x = &v;
    return &x;
}

#21


没看到你返回的局部指针

#22


引用 17 楼 zilaishuichina 的回复:
Quote: 引用 11 楼 u012186949 的回复:

那再来看一个吧。
int* test(int b)
{
    int a=0;//局部变量
    a=b; //行参复制给a
    int * p=&a ; //定义一个int* 的指针,把变量a的地址给p
  
    return p; //返回p。这个p是不是局部变量的指针?我觉得是的

}

 int * result=test(5);
    
    NSLog(@"%d",*result); 
输出结果还是5.我分析的对么?


这个p是局部变量的指针,返回的result里面 目前是5,因为result指向的内存(在栈上)目前没有被破坏,因为没有其他函数调用
你可以这样

int* test(int b)
{
int a=0;//局部变量
a=b; //行参复制给a
int * p=&a ; //定义一个int* 的指针,把变量a的地址给p

return p; //返回p。这个p是不是局部变量的指针?我觉得是的

}
void test2()
{
int a[10];
for (int i = 0; i < 10; i++)
{
a[i] = i;
}
}

int *result=test(5);
printf("%d\n", *result); //此时是5
test2();
printf("%d\n", *result); //此时是一个错误的值
嗯嗯,我明白了。感谢你的解说,我返回的是个栈上的指针。一调用其他函数。确实指向了一个未知的数

#23


谢谢各位大神的讲解。我仔细的研究了一下c/c++内存的分配,和函数的调用过程。后面那个test返回的是栈指针(指向的是栈上的一块内存)。这个一调用其他函数,那个值就会被覆盖。也明白了函数的调用过程。

#1


C++里面说函数的返回值不可以返回指向局部变量的指针。这个是绝对的么?C++里面说函数的返回值不可以返回指向局部变量的指针。这个是绝对的么?

#2


你给的例子不是指向局部变量的指针

#3


char* p=0;
    p=str ;//  str  并不是 局部变量 , 而 是 输入 参数。

#4


char* str=getStr("hello"); //这个 hello是局部变量? 明明是常量字符串 在全局变量数据区  不是在栈中

#5


不是不可以返回。返回的只不过是个野指针而已,只要你不怕内存崩掉。
你给的例子跟标题没半毛钱关系。

#6


C++里面说函数的返回值不可以返回指向局部变量的指针  ----- 实际就是指向变量A的指针,是看A的生存期,也就是说函数返回后,A是否还在生存期

#7


1. 这个函数返回的并不是局部变量的指针,而是调用这个函数时实参表达式的指针,LZ的例子与标题不是一回事

2.函数可以返回“static 局部变量”的指针,可以返回本函数调用malloc( )函数得到的指针

#8


WinSock中的常用函数

char *inet_ntoa(); 这就是一个返回局部变量的例子。有两点需要注意

1、返回的是局部变量,但是是静态的

2、使用了tls

#9


我说的局部变量指的是p哦,那个指针。指针本身就是一个变量,只不过它存的是另一个变量的地址而已。和输入参数无关,我也可以换一参数去调用。不一定getStr("hello")这样去调用。   如下。还是可以得到hello。这个arr总不是在全局变量数据区了吧
char arr[6]={'h','e','l','l','o'};
    char* str=getStr(arr);
    NSLog(@"%s",str);

#10


感谢各位的回答,还是有点不明白,要是哪位大神能写个demo,分析下就再好不过了。

#11


那再来看一个吧。
int* test(int b)
{
    int a=0;//局部变量
    a=b; //行参复制给a
    int * p=&a ; //定义一个int* 的指针,把变量a的地址给p
  
    return p; //返回p。这个p是不是局部变量的指针?我觉得是的

}

 int * result=test(5);
    
    NSLog(@"%d",*result); 
输出结果还是5.我分析的对么?

#12


引用 9 楼 u012186949 的回复:
我说的局部变量指的是p哦,那个指针。指针本身就是一个变量,只不过它存的是另一个变量的地址而已。和输入参数无关,我也可以换一参数去调用。不一定getStr("hello")这样去调用。   如下。还是可以得到hello。这个arr总不是在全局变量数据区了吧
char arr[6]={'h','e','l','l','o'};
    char* str=getStr(arr);
    NSLog(@"%s",str);


1.“我说的局部变量指的是p哦,那个指针”,那返回就应该是&p,但与该函数的返回值类型不符,正确的应该是char **

2.char arr[6]={'h','e','l','l','o'};
    char* str=getStr(arr);
arr是指向‘h'的指针----(数组名在许多场合是首元素的指针),即arr实际是&arr[0]
调用时传递给形参str,即str=&arr[0]
函数中:
 p=str

p=&arr[0]
返回p,返回p 即返回p的内容&arr[0],这不是局部变量p的指针,而是实参表达式的指针&arr[0].而你的arr[ ]不是这个被调函数的局部变量,而是主调函数提供的

#13



int * FunRetRef()
{
    int a = 0;

    cin>>a;

    printf("FunRetRef Get inputFromUsr == %d\n", a);

    return &a;
}

void TheThirdFunc( int nVal)
{
    int i = 0;
    int arr[10] = {0};

    for ( int i = 0; i < 10; i++ )
    {
        arr[i] = i * nVal;
    }

    for (int i = 0; i < 10; i++)
    {
        cout<<arr[i]<<" ";
    }

    cout<<endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    int *pRet = FunRetRef();
    cout<<"nRet Value == "<<*pRet<<endl;

    TheThirdFunc(argc);

    cout<<"nRet Value == "<<*pRet<<endl;

    return 0;
}


我闲的蛋疼。。 楼主自己调试看看吧。

#14


引用 13 楼 TheNewIpad 的回复:

int * FunRetRef()
{
    int a = 0;

    cin>>a;

    printf("FunRetRef Get inputFromUsr == %d\n", a);

    return &a;
}

void TheThirdFunc( int nVal)
{
    int i = 0;
    int arr[10] = {0};

    for ( int i = 0; i < 10; i++ )
    {
        arr[i] = i * nVal;
    }

    for (int i = 0; i < 10; i++)
    {
        cout<<arr[i]<<" ";
    }

    cout<<endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    int *pRet = FunRetRef();
    cout<<"nRet Value == "<<*pRet<<endl;

    TheThirdFunc(argc);

    cout<<"nRet Value == "<<*pRet<<endl;

    return 0;
}


我闲的蛋疼。。 楼主自己调试看看吧。
感谢大神。我会好好研究一下。

#15


返回的指向局部变量的指针是指向了一个已经被标记为“未使用”的内存,当然如果那个内存存的值是5的话系统也不会去清除这块内存的值,如果你打印这个内存的值 就会出现不确定因素因为 不知道什么时候内存值就会被改变。

#16


你返回的是指向局部变量的指针吗?显然不是啊

#17


引用 11 楼 u012186949 的回复:
那再来看一个吧。
int* test(int b)
{
    int a=0;//局部变量
    a=b; //行参复制给a
    int * p=&a ; //定义一个int* 的指针,把变量a的地址给p
  
    return p; //返回p。这个p是不是局部变量的指针?我觉得是的

}

 int * result=test(5);
    
    NSLog(@"%d",*result); 
输出结果还是5.我分析的对么?


这个p是局部变量的指针,返回的result里面 目前是5,因为result指向的内存(在栈上)目前没有被破坏,因为没有其他函数调用
你可以这样

int* test(int b)
{
int a=0;//局部变量
a=b; //行参复制给a
int * p=&a ; //定义一个int* 的指针,把变量a的地址给p

return p; //返回p。这个p是不是局部变量的指针?我觉得是的

}
void test2()
{
int a[10];
for (int i = 0; i < 10; i++)
{
a[i] = i;
}
}

int *result=test(5);
printf("%d\n", *result); //此时是5
test2();
printf("%d\n", *result); //此时是一个错误的值

#18


不可以返回指向局部非静态对象的指针 

顺便不是绝对的 
只是返回了不可以使用 没什么意义罢了

#19


能返回,你敢用么?

#20



// 哈哈,看你下次还敢返回局部变量的地址(指针)吗?
int *GetAddress()
{
    int x = 10;
    return &x;
}

int **GetAddress()
{
    int v = 10;
    int * x = &v;
    return &x;
}

#21


没看到你返回的局部指针

#22


引用 17 楼 zilaishuichina 的回复:
Quote: 引用 11 楼 u012186949 的回复:

那再来看一个吧。
int* test(int b)
{
    int a=0;//局部变量
    a=b; //行参复制给a
    int * p=&a ; //定义一个int* 的指针,把变量a的地址给p
  
    return p; //返回p。这个p是不是局部变量的指针?我觉得是的

}

 int * result=test(5);
    
    NSLog(@"%d",*result); 
输出结果还是5.我分析的对么?


这个p是局部变量的指针,返回的result里面 目前是5,因为result指向的内存(在栈上)目前没有被破坏,因为没有其他函数调用
你可以这样

int* test(int b)
{
int a=0;//局部变量
a=b; //行参复制给a
int * p=&a ; //定义一个int* 的指针,把变量a的地址给p

return p; //返回p。这个p是不是局部变量的指针?我觉得是的

}
void test2()
{
int a[10];
for (int i = 0; i < 10; i++)
{
a[i] = i;
}
}

int *result=test(5);
printf("%d\n", *result); //此时是5
test2();
printf("%d\n", *result); //此时是一个错误的值
嗯嗯,我明白了。感谢你的解说,我返回的是个栈上的指针。一调用其他函数。确实指向了一个未知的数

#23


谢谢各位大神的讲解。我仔细的研究了一下c/c++内存的分配,和函数的调用过程。后面那个test返回的是栈指针(指向的是栈上的一块内存)。这个一调用其他函数,那个值就会被覆盖。也明白了函数的调用过程。