c语言怎样将局部变量的指针传出来,c语言中函数返回局部变量的指针(一些容易犯错的地方)...

写这篇博客是我一直以来遇到的一个指针的问题-----对于返回一个局部对象的指针到底能否达到预期的效果?我也还在摸索之中,能给大家有所启发吧。

首先我先给出一些最近我做题过程中遇到的一些问题。

比如很经典的strcpy函数的编写,估计很多人早已看过了。转载的文中,给出了2分到10分的样式。着实让人感叹

2 分

void strcpy( char *strDest, char *strSrc )

{

while( (*strDest++ = * strSrc++) != ‘\0’ );

}

4 分

void strcpy( char *strDest, const char *strSrc )

//将源字符串加const,表明其为输入参数,加2 分

{

while( (*strDest++ = * strSrc++) != ‘\0’ );

}

7 分

void strcpy(char *strDest, const char *strSrc)

{

//对源地址和目的地址加非0 断言,加3 分

assert( (strDest != NULL) && (strSrc != NULL) );

while( (*strDest++ = * strSrc++) != ‘\0’ );

}

10 分

//为了实现链式操作,将目的地址返回,加3 分!

char * strcpy( char *strDest, const char *strSrc )

{

assert( (strDest != NULL) && (strSrc != NULL) );

char *address = strDest;

while( (*strDest++ = * strSrc++) != ‘\0’ );

return address;

}

[可是,到最后我就有问题了,对于10分的这个strcpy函数的描述,有一点我断言它肯定有错误----就是它返回的是一个局部对象的指针,而在以前我一直“坚信”返回一个局部对象的指针是错误的,之所以认为它会出错是因为在函数返回的过程中,它会释放内存,内存中的数据变得不可预料了。而且在看c++ primer的书中也是这么说的,但它没有给出什么实际的例子。(如果是我的软件有问题或者大家有通过编译的,欢迎指出交流)

为了能得到验证,我用vc++6.0在自己的电脑上尝试了一下,果然确实出现了错误,尽管编译什么的都通过了。很惭愧的是,自己不会真正的使用vc++,连怎么去看它的内存,地址,参数的都不会,只会也只知道看结果。。深感惭愧,没有听前辈的话--《c语言深度解剖》。]----------------------

PS:(20130504)最近有遇到类似的的题目,又自己检验了一遍,strcpy()函数没有出错。对于是否能返回局部对象的指针问题有待进一步解决。。。。

随后我又想起了以前自己做过的一道题就是有关个getmemory()函数的基本用法,里面也涉及到了很多有关指针的问题。设想,难道返回指针都是错误的?但是,翻翻书,在谭浩强的课本中,299页建立链表的时候明明返回的也是指针。这究竟又是为什么?最后自己在网上苦心的查找资料。

有人是这么解释的:“函数不能通过返回指向栈内存的指针,但对于堆内存的指针却是可以的”。以前一直对栈和堆的认识也不是很深,又顺便网上查了些资料有关数据存储的,就是下面我提到的参考博客之一,很有用。

以下给出一道题,大家分析分析:

1.

#include

char *returnStr()

{

char *p="hello world!";

return p;

}

int main()

{

char *str;

str=returnStr();

printf("%s\n", str);

return 0;

}

2.

#include

char *returnStr()

{

char p[]="hello world!";

return p;

}

int main()

{

char *str;

str=returnStr();

printf("%s\n", str);

return 0;

}

大家也可以亲自去编译一下。不知道大家会认为以上的哪个可以正常运行,而哪个又不可以。仅仅是一个字符串指针和字符数组的区别。第一个,“hello world!”是字符串常量,存放在常量存储区,而这些内存中的数据是不会随着函数的调用完成而释放的,只有程序结束了才会消亡,因此当把它的地址返回时,还能找到这些内存存放的数据;有人可能会问,难道第二个中的“hello world!”难道不是存储在常量存储区吗?不都是一样的吗?它是存储在常量存储去,但是它是作为赋值给p的数组元素,而我们此时返回的是数组p的首元素地址,而数组p存储的是“hello world!”的副本,也就是将常量存储区的数据存储到了数组里,而在数组里面的数据时存放在栈里面的;这样的话,在函数返回的时候,要进行出栈也就是内存的释放(这些内存里面到底存储的是什么数据也就不得而知了),返回的是一个内存已经释放了的指针,所以会出现错误。

对于指针方面的问题,将继续收集;以上的内容有纰漏之处希望大家指出。

参考的一些博客资料:

http://blog.chinaunix.net/uid-11959329-id-3268560.html

http://www.cnblogs.com/Kevin_z/archive/2010/03/05/1679031.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值