C语言中以字符串为返回值的函数的问题,困扰我好几天了

下面是课本上讲述野指针时的范例代码#include<stdio.h>#include<string.h>char*Getstr(void);intmain(){char*... 下面是课本上讲述野指针时的范例代码

#include <stdio.h>
#include <string.h>
char *Getstr(void);
int main()
{
char *ptr = NULL;
printf("Input a string");
ptr = Getstr();
puts(ptr); //试图使用野指针,导致程序输出出现乱码
}
char *Getstr(void)
{
char s[80];
scanf("%s",s);
printf("s = %p\n",s);

return s;
}
但是当我把程序改成下面这样时,虽然仍然有警告错,但是却能正确输出
#include <stdio.h>
#include <string.h>
char *Getstr(void);
int main()
{
char str[80];
printf("Input a string");
strcpy(str,Getstr());//没有直接用Getstr()的返回值,而是把Getstr()的内容复制给str
puts(str);
}
char *Getstr(void)
{
char s[80];
scanf("%s",s);
printf("s = %p\n",s);
return s;
}
再次实验,把puts函数改成printf,仍然能得到正确的结果,也就是把最开始的代码改成下面这样
#include <stdio.h>
#include <string.h>
char *Getstr(void);
int main()
{
char *ptr;
printf("Input a string");
ptr = Getstr();
printf("%s",ptr); //不用puts,改用printf
}
char *Getstr(void)
{
char s[80];
scanf("%s",s);
printf("s = %p\n",s);
return s;
}
为什么会有这种状况?按书上说,子函数退出之后,所占有的栈内存被释放,为什么还能被strcpy和printf使用,得到正确的输出?更奇怪的是,为什么只有puts函数不能使用函数返回的字符串,而输出乱码?
以上代码在VC++6和gcc下运行结果相同。
展开
 我来答
寻森良Z
推荐于2016-07-27 · TA获得超过368个赞
知道小有建树答主
回答量:124
采纳率:0%
帮助的人:131万
展开全部
野指针的含义:超出生命周期的指针,包括函数内局部数据的指针(static修饰数据除外,它不在栈上)和已经被释放了的动态分配内存区。
char *Getstr(void)

{
char s[80];
scanf("%s",s);
printf("s = %p\n",s);
return s;
}
这个函数,是将栈内局部变量的地址返回给调用者,调用者拿到的指针属于典型的超出生命周期的指针,对它的使用会不会引起错误,依赖于进一步的操作,本身行为就是不可预期的。
可以认为:使用strcpy和printf并没有破坏这个内存区域,即没有对这部分内存做修改,因此运行可以得到你期待的结果。但puts的运行修改了这部分内存区,导致你看到的都是乱码。

避免野指针带来的不确定性:
你可以使用
char *Getstr(void)
{
static char s[80];
scanf("%s",s);
printf("s = %p\n",s);
return s;
}
用这个函数,你的所有逻辑都不变。
或者
char *Getstr(void)
{
char *s = malloc(80);
scanf("%s",s);
printf("s = %p\n",s);
return s;
}
要记得在这个调用后得到的ptr,一定要用free(ptr)。
kaixingui2012
2012-12-05 · TA获得超过4.2万个赞
知道大有可为答主
回答量:1.4万
采纳率:81%
帮助的人:6439万
展开全部
一、不要使用局部变量作为返回值来使用!因为,子函数一结束,局部变量就被释放。
当有其它程序用到该内存数据时,数据就会发生变化,
而若没有人使用,则数据不会发生变化。
二、一定要使,则将局部变量定义成静态变量,相当于定义一个全局变量:
char *Getstr(void)
{
static char s[80]; //加上static
scanf("%s",s);
printf("s = %p\n",s);
return s;
}
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
tianchangxi
2012-12-05
知道答主
回答量:18
采纳率:0%
帮助的人:7.7万
展开全部
子函数结束之后所占的内存被释放掉意思是“这片内存空间从释放掉之后就可以再次被其他程序使用”,但是这片空间里的内容有没有改变就不好说了,程序输出正确的结果只能说明在你函数返回到调用fputs这段时间里这片内存没有被重新赋其他的值。虽然结果是正确的,语法上也没有错误,但是这种写法是不对的!只要是被释放掉的内存空间绝对不可以再次引用!
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友91292b5
2012-12-05 · TA获得超过484个赞
知道小有建树答主
回答量:351
采纳率:72%
帮助的人:97万
展开全部
#include <stdio.h>
#include <string.h>
char *Getstr(void);
int main()
{
char str[80];
printf("Input a string");
strcpy(str,Getstr());//没有直接用Getstr()的返回值,而是把Getstr()的内容复制给str
puts(str);
return 0;
}
char s[80];//声明为全局变量
char *Getstr(void)
{
scanf("%s",s);
printf("s = %p\n",s);
return s;
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式