LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1880|回复: 11

c语言新手-关于函数返回值问题

[复制链接]
发表于 2006-1-4 02:52:44 | 显示全部楼层 |阅读模式
c语言的函数返回值如果是指向内部自动变量的指针那么在函数返回的时候该自动变量会被自动清空或覆盖,除非该内部变量是static或malloc分配的,下面是两个例子请教高手原因:

int* test1() {
   int i = 10;
   int *n = &i;
   return n;
}
该函数正常



char* test2() {
   char str[] = "hello welcome!";
   return str;
}
该函数工作不正常

我得到的基本结论是通用数据的声明并初始化实际上是一个常量的声明如int i = 0;
char *str = "hello".... ,在函数返回并结束时系统并不会去覆盖或清空常量内存,
但是数组的声明如char str[] = "hello"则是一个自动变量的声明,系统调用完毕必被清空或覆盖

以上只是我想的,希望高手能指点一下,现在觉得学c语言真的很有意思,觉得什么都得自己做,
而用起c#或java等,根本就不用去担心这些,所以底层的东西懂得的比较少!!!!!!!!!!!!
发表于 2006-1-4 11:55:57 | 显示全部楼层
不能那样认为,你所说的前一个正常,只是说明刚好那个地址没有被覆盖而已,就像下面这样:
  1. [rick@Fedora-Core test]$ cat test.c
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. int* test()
  5. {
  6.         int i = 10;
  7.         int* n = &i;
  8.         return n;
  9. }
  10. int main()
  11. {
  12.         int* x = test();
  13.         printf("lalalalala,%d\n");
  14.         printf("%d\n",*x);
  15.         return 0;
  16. }
  17. [rick@Fedora-Core test]$ gcc test.c
  18. [rick@Fedora-Core test]$ ./a.out
  19. lalalalala,10
  20. 10
复制代码

但是,很有可能会被覆盖,就像下面这样:
  1. [rick@Fedora-Core test]$ cat test.c
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. int* test()
  5. {
  6.         int i = 10;
  7.         int* n = &i;
  8.         return n;
  9. }
  10. int main()
  11. {
  12.         int* x = test();
  13.         printf("lalalalala,%d\n",1);
  14.         printf("%d\n",*x);
  15.         return 0;
  16. }
  17. [rick@Fedora-Core test]$ gcc test.c
  18. [rick@Fedora-Core test]$ ./a.out
  19. lalalalala,1
  20. 1
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-1-4 14:50:24 | 显示全部楼层
小弟明白了,只是暂时没被覆盖而已,如果再调用其他函数,可能其他的数据会被压入堆栈并替换调它,
那也就是说处理这类问题只能使用在堆上分配的内存了,并手动释放,那么岂不是要让用户自己去给定分配内存的大小,希望那位高手能给出一个例子来!!! 感激不尽!!!
回复 支持 反对

使用道具 举报

发表于 2006-1-4 16:38:27 | 显示全部楼层

  1. #include <stdio.h>

  2. char* test()
  3. {
  4.         int a[10000];   //在栈中分配足够大的空间,尽量防止str[6]在test返回后被被覆盖
  5.         char str[6]="hello";
  6.         return str;
  7. }
  8. int main()
  9. {
  10.         char * p=test(); //返回局部变量地址
  11.     //  [color="Red"]  printf("str :%s\n",*p); //仍然提示段错误[/color] <--------低级错误
  12.        printf("str :%s\n", p);
  13.        return 0;
  14. }
复制代码

不明白为什么仍然出错。
回复 支持 反对

使用道具 举报

发表于 2006-1-4 16:45:31 | 显示全部楼层
to Lolita: 因为你有个笔误:
  1. printf("str :%s\n",*p); //仍然提示段错误
复制代码
应为:
  1. printf("str :%s\n",p); //仍然提示段错误
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-1-4 16:45:37 | 显示全部楼层
我真晕了。。。谢谢提醒,我还以为我哪里想错了呢
回复 支持 反对

使用道具 举报

发表于 2006-1-4 17:01:01 | 显示全部楼层
Post by aishen944
小弟明白了,只是暂时没被覆盖而已,如果再调用其他函数,可能其他的数据会被压入堆栈并替换调它,
那也就是说处理这类问题只能使用在堆上分配的内存了,并手动释放,那么岂不是要让用户自己去给定分配内存的大小,希望那位高手能给出一个例子来!!! 感激不尽!!!

分配/释放直接用malloc/free就行了啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-1-4 18:07:25 | 显示全部楼层
呵呵,我知道用malloc/free就可以了,但是我想不可能是在函数内部free掉吧,要不然返回值就不正确了!!! 照这样岂不是每次使用完了函数都要在外部明确释放内存!!

这只是我的一点想法!! 请大哥们指正!!!
回复 支持 反对

使用道具 举报

发表于 2006-1-4 18:11:36 | 显示全部楼层
嗯,是啊.

ps: 说我字数不够,所以再加几个字
回复 支持 反对

使用道具 举报

发表于 2006-1-4 18:24:25 | 显示全部楼层
Post by aishen944
呵呵,我知道用malloc/free就可以了,但是我想不可能是在函数内部free掉吧,要不然返回值就不正确了!!! 照这样岂不是每次使用完了函数都要在外部明确释放内存!!

这只是我的一点想法!! 请大哥们指正!!!

这是常用的做法,用完之后一定要记得自己free。如果自己忘记free了,就会造成内存泄漏。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表