c语言 返回局部变量 局部指针 局部数组

deep_pro 2009-08-07 04:22:23
纯c(非c++下的c)

返回局部变量 、局部指针、 局部数组
这三种情况,
那些是正确的,那些是错误的容易出问题的?



我已经知道返回局部指针不正确,但如果局部指针指向静态区常量还是不会出错的。
但是返回局部变量 和 返回局部数组还不清楚。

希望有深度的回答。
...全文
1363 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
woshiqian84425 2011-06-21
  • 打赏
  • 举报
回复
可不可以这么个理解呢?return返回了指针指向的堆空间的副本,而指针却是在栈中的,你没有把他给释放掉,所以这个指针还仍可以访问这段堆内存内的值;而如果是返回数组名的话应该也是如此,只不过你返回的是局部变量,在堆中会被很快释放掉(用完就被释放);
wjlsmail 2009-11-04
  • 打赏
  • 举报
回复
Agree with layer7, 10, 14, 19
cynthiajj 2009-10-09
  • 打赏
  • 举报
回复
学习学习~~~~
ies_sweet 2009-08-08
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 sh365 的回复:]
我觉得这个主要是要了解一下变量、参数的作用域的问题,以及参数是如何传递的问题。
在C专家编程里面有比较详细的说明
[/Quote]

建议楼主读一下
《C专家编程》
然后你就会豁然开朗了!

这个问题是C比较深入的东西了,
一言难尽啊
deep_pro 2009-08-08
  • 打赏
  • 举报
回复
很多很好很强大的回复
谢谢各位
chenee543216 2009-08-07
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 abcdef0966 的回复:]
...........
对比局部变量,返回它,就是让上面说的临时变量得到它的一个副本嘛,然后你想对这个副本干嘛就干嘛咯
[/Quote]
上面说的虽然深入,但抽象了点,:)
下面针对这位哥们的深入,希望能够浅出!

副本:(非山口山副本!)
用深入的概念讨论一下副本,
int test()
{
......
int i=3;
return i;//这里返回i的副本
}
对应汇编: 手头没有编译器,随便写,意思意思
__test:
push
mv eax 3 ;这里返回i的副本
pop
ret
所谓的”返回 i 这个局部变量的副本“,其实就是他的值3放到exa中。

语言表达能力欠缺,希望大家能够明白我的意思。
chenee543216 2009-08-07
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 cheng_fengming 的回复:]
上面各位说的很好了,我就提一点,其实这些都是关于变量的生存周期和变量作用域的问题。
[/Quote]
这个哥们说的好!只是书面了一些。你喜欢深的看下面

我来深一点!
return?什么叫return?程序原本是没有return的,自从有了C这样的高级语言后才有return这种形式。
是形式,真正实现还是汇编。对应寄存器eax !!(x86体系)

那么什么样的东西可以return呢?返回局部变量 、局部指针、 局部数组。。。。
只要是你在后边能够正常访问的东西即可,text,data中的持久数据肯定是可以的。那么stack中的呢?这要看你的程序返回后stack是否还有效?如果操作系统或者你自己的系统,在程序返回后不主动清空stack,那么你完全可以使用它。

C的美丽就在于直接操作内存和cpu,从机器运行本质看问题。一切问题都不是问题。
sh365 2009-08-07
  • 打赏
  • 举报
回复
我觉得这个主要是要了解一下变量、参数的作用域的问题,以及参数是如何传递的问题。
在C专家编程里面有比较详细的说明
cheng_fengming 2009-08-07
  • 打赏
  • 举报
回复
上面各位说的很好了,我就提一点,其实这些都是关于变量的生存周期和变量作用域的问题。
  • 打赏
  • 举报
回复
条例说的没错,但是如果返回的是堆上的局部指针,而不是栈上的,就没有问题,当然,在这种情况下,一定要记得释放内存。

返回的是堆上的局部指针
也是不好的写法,这种情况其实你需要智能指针。

BuleRiver 2009-08-07
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 hairetz 的回复:]
总之,条款里说:禁止返回局部变量的指针或引用。
是有道理的
[/Quote]
条例说的没错,但是如果返回的是堆上的局部指针,而不是栈上的,就没有问题,当然,在这种情况下,一定要记得释放内存。
BuleRiver 2009-08-07
  • 打赏
  • 举报
回复
这还要分情况讨论,例如局部指针:

int * func(void)
{
int i = 10;
int * p = &i;
return p;
}

是有问题的,如果这样:

int * func(void)
{
int * p = molloc(10 * sizeof(int));
return p;
}

在用的时候这样:

int * q = func();
//...
free(q);

就没有问题
  • 打赏
  • 举报
回复
总之,条款里说:禁止返回局部变量的指针或引用。
是有道理的
ies_sweet 2009-08-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 hairetz 的回复:]
返回局部变量,其实是拷贝的副本,所以没问题。
返回局部指针,指针指向的内容会随函数失效,所以不妥。
返回局部数组,你想用什么语法返回?一般没试过返回数组。
[/Quote]

UP
小宇去读书 2009-08-07
  • 打赏
  • 举报
回复
说的很好啊
整个return机制就大概这么多吧,不知还有人知道return还能返回什么其他的类型吗?
baihacker 2009-08-07
  • 打赏
  • 举报
回复
局部变量:如果是值上的返回,没问题.
局部指针:和指针的指向有关.
局部数组:不能返回数组的.
lzy0001sl 2009-08-07
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 supermegaboy 的回复:]
引用楼主 deep_pro 的回复:
纯c(非c++下的c)

返回局部变量 、局部指针、 局部数组
这三种情况,
那些是正确的,那些是错误的容易出问题的?


我已经知道返回局部指针不正确,但如果局部指针指向静态区常量还是不会出错的。
但是返回局部变量 和 返回局部数组还不清楚。

希望有深度的回答。


局部变量里面还得分为自动还是静态,两者结果是不同的,得分开描述。

数组是不能作为函数的返回值的,原因是数组名是一个不可修改的左值,例如这样的代码是非法的:

int func( void )[5];

返回一个数组一般用返回指向这个数组的指针代替,而且这个指针不能指向一个自动数组,因为函数结束后自动数组被抛弃,但可以返回一个指向静态局部数组的指针,因为静态存储期是从对象定义到程序结束的。例如:

int* func( void )
{
    static int a[10];
    ........
    return a;
}

局部变量也分局部自动变量和局部静态变量,由于c返回的是值,因此返回一个局部变量是可以的,无论自动还是静态,因为这时候返回的是这个局部变量的值,但不应该返回指向局部自动变量的指针,因为函数调用结束后该局部自动变量被抛弃,这个指针指向一个不再存在的对象,是无意义的。但可以返回指向局部静态变量的指针,因为静态变量的生存期从定义起到程序结束。例如:

int func()
{
      int a;
      ....
      return a;    //允许
}                   

int * func()
{
      int a;
      ....
      return &a;    //无意义,不应该这样做
}

局部指针跟上面所述的局部变量一样。可以返回一个局部指针的值,也可以返回一个局部静态指针的地址,但不应该返回一个局部自动指针的地址。
[/Quote]
复议!
DZW_0714 2009-08-07
  • 打赏
  • 举报
回复
学习
飞天御剑流 2009-08-07
  • 打赏
  • 举报
回复
[Quote=引用楼主 deep_pro 的回复:]
纯c(非c++下的c)

返回局部变量 、局部指针、 局部数组
这三种情况,
那些是正确的,那些是错误的容易出问题的?


我已经知道返回局部指针不正确,但如果局部指针指向静态区常量还是不会出错的。
但是返回局部变量 和 返回局部数组还不清楚。

希望有深度的回答。
[/Quote]

局部变量里面还得分为自动还是静态,两者结果是不同的,得分开描述。

数组是不能作为函数的返回值的,原因是数组名是一个不可修改的左值,例如这样的代码是非法的:

int func( void )[5];

返回一个数组一般用返回指向这个数组的指针代替,而且这个指针不能指向一个自动数组,因为函数结束后自动数组被抛弃,但可以返回一个指向静态局部数组的指针,因为静态存储期是从对象定义到程序结束的。例如:

int* func( void )
{
static int a[10];
........
return a;
}

局部变量也分局部自动变量和局部静态变量,由于c返回的是值,因此返回一个局部变量是可以的,无论自动还是静态,因为这时候返回的是这个局部变量的值,但不应该返回指向局部自动变量的指针,因为函数调用结束后该局部自动变量被抛弃,这个指针指向一个不再存在的对象,是无意义的。但可以返回指向局部静态变量的指针,因为静态变量的生存期从定义起到程序结束。例如:

int func()
{
int a;
....
return a; //允许
}

int * func()
{
int a;
....
return &a; //无意义,不应该这样做
}

局部指针跟上面所述的局部变量一样。可以返回一个局部指针的值,也可以返回一个局部静态指针的地址,但不应该返回一个局部自动指针的地址。
abcdef0966 2009-08-07
  • 打赏
  • 举报
回复
[Quote=引用楼主 deep_pro 的回复:]
纯c(非c++下的c)

返回局部变量 、局部指针、 局部数组
这三种情况,
那些是正确的,那些是错误的容易出问题的?


我已经知道返回局部指针不正确,但如果局部指针指向静态区常量还是不会出错的。
但是返回局部变量 和 返回局部数组还不清楚。

希望有深度的回答。
[/Quote]

你说的返回局部数组就考虑了,不知道你怎么返回的

考虑返回局部变量和局部变量指针

return语句
调用函数的时候,会在调用函数的地方生成一个临时变量,return语句将你要的返回值赋给这个临时变量,也就是临时变量得到返回值的一个副本

其实很简单,如果指针指向的是一段栈区(局部变量就放在这里啦),函数结束后返回,这段栈被释放了,你能通过return得到指针的副本,但是这是指针指向的空间已经无效啦,你让指针咋办呢?

对比局部变量,返回它,就是让上面说的临时变量得到它的一个副本嘛,然后你想对这个副本干嘛就干嘛咯
加载更多回复(5)

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧