函数返回值的问题(郁闷中)

bigchief 2004-07-12 01:35:18
#include <stdio.h>
char *Func(void)
{
char str[20]="hello world";
return str;
}

main()
{
printf("%s\n",Func());
return 0;
}
这样就能返回hello world,如果改成
char str[]="hello world",就不行了,能说说原因吗?
...全文
153 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
runall 2004-07-21
  • 打赏
  • 举报
回复
函数不能返回在栈中分配内存空间的指针
mainSean 2004-07-21
  • 打赏
  • 举报
回复
up
疯狂的技术宅 2004-07-21
  • 打赏
  • 举报
回复
该说的楼上的都说了,只好灌一句
gyj_china 2004-07-21
  • 打赏
  • 举报
回复
#include <stdio.h>
char str[20];
char *Func(void)
{
strcpy(str,"hello world");//注意变量的生命周期
return str;
}

main()
{
printf("%s\n",Func());
return 0;
}
hchinside 2004-07-21
  • 打赏
  • 举报
回复
你根本就不应该这么写
kaphoon 2004-07-21
  • 打赏
  • 举报
回复
返回局部变量的指针
在标准中讲是不可定义的,也就是不可预测的
所以你的结果本身就没有任何意义~~
qwertasdfg123 2004-07-12
  • 打赏
  • 举报
回复
楼主是输不出来的。
str一个临时变量,函数返回时会自动释放内存。


#include <stdio.h>
#include <sstream>
std::string Func(void)
{
std::ostringstream temp;
temp << "Hello World";
return temp.str();
}


main()
{
printf("%s\n",Func().c_str());
return 0;
}

WangOutVcInJava 2004-07-12
  • 打赏
  • 举报
回复
在函数中"Hello World"是在系统分配的只读区中存在的。
char str[20]="hello world";是把系统只读区内容拷贝到str为首地址的函数Func的栈中,
是局部变量。在Func函数结束后,esp(栈指针)会复位。return str;会返回str的首地址,这时str指向的内容仍为"hello world",但是跟着调用printf(两次),会压入栈两个参数(从右到左),和函数入口地址,以及一些寄存器edi...,这样会把str指向的内容覆盖。因而,在主程序中print出现乱码。

解决问题的方法我知道有两种:
1
bianliuwei(C++一辈子)说的是一种,即
char* str="hello world";这样return str;返回的是系统只读区指向"hello world"的地址。
但是,这样做是没有保证的。第一,可能被后继数据覆盖;第二,这是只读的,不方便操作。
2
static char str[20]="hello world";return str;
这样系统会在编译时,在static存储区,开辟空间存储"hello world",str指向相应的地址。
这样,可以对其进行操作,(这不是只读的)。
firesgoo 2004-07-12
  • 打赏
  • 举报
回复
char str[20]="hello world";
分配的空间,有未被赋值,当
printf("%s\n",Func());时,
当然会出现乱码
bianliuwei 2004-07-12
  • 打赏
  • 举报
回复
楼主:你的机子上能得到你说的结果吗?我运行了一下,乱码!
为何不这样呢:
#include <stdio.h>
char* Func()
{
char* str="hello world";
return str;
}

int main()
{
printf("%s\n",Func());
return 0;
}
自己下载正式版2.3,二进制下自己破解。参考偷梁换柱破解SkinMagic_百度文库的文档,思想是PostMessageA替换MessageBoxA。下面是帖子的具体内容 不知道有多少像本人一样一直热爱着vc的人存在,应该很多吧.虽然CB也用的是c++的语法,但是由于是个人偏激吧,不太喜欢,所以就一直忍受着做界面的痛苦.用Vc写程序的都知道,MFC做界面是多么痛苦的事情,动不动就要继承,封装....十分的郁闷。以后前段时间让我遇到了SkinMagicToolkit,才知道,世界上既然还有那么可爱的软件存在(帮作者做一下广告先),简单的调用几句代码,就可以改变界面皮肤~换皮肤也很简单。真是个好东西~.好了,不说多废话了,开始。 我下载的是SkinMagicToolkit2.21.下载回来以后,发现按照例子调用以后,可以是可以改变皮肤,但是都会在程序界面显示前跳出一个对话框,显示内容是:ThisapplicationusestrialversionofSkinMagicToolkit.Youcanregisterathttp://www.appspeed.com 真难看,破解!把这个难看的对话框去掉。先检查壳。结果是没有~好~用W32dsm8.93文版.先进行静态分析.SkinMagic里所有的函数其实就是在SkinMagicTrial.dll这里面了.用W32dsm8.93打开SkinMagicTrial.dll。然后"参考"->"串式参考".找到对话框信息.一直往下翻.看见这个信息"Thisapplicationusestrialversion",双击。这个时候,程序代码来到了:100061816878BC0510push1005BC78.字符信息就是在这里入栈的.往下看几行,把MessageBoxA的4个参数都入栈了以后,再下两行就是MessageBoxA函数的调用处了,在:10006192FF150c040510,这里就是调用MessageBoxA的地方.好的,马上用最简单的办法,把这里的入栈的4个参数都用nop给替换掉.我用的是Hiewv6.81。不一会,就把这4个push*****替换成了nop。马上运行已经写好的程序,因为程序是调用SkinMagicTrial.dll的,所以不用改任何程序的代码,就可以运行了。结果发现,跳出错误对话筐,说程序初始化错误,就退出了程序.....真郁闷....难道程序在其他的地方检查了Eax寄存器?Eax寄存器是用来保存每个函数调用完以后的返回值的.算了,我也懒得麻烦去做其他的事情了,要的就是爆破.仔细想一下,有什么函数也是调用4个参数的,而且要SkinMagicTrial.dll已经倒入的。有了! PostMessageA,马上看一下PostMessageA在SkinMagicTrial.dll的地址."菜单"->"函数"->"输入",然后找到PostMessageA.双击,看见了PostMessageA的调用地址: 10023FF1FF15C4030510.好的,等一下就可以在:10006192FF150C040510,把FF150C040510替换成为FF15C4030510就可以了.因为PostMessageA也有返回值.呵呵。破解成功。这样,运行的时候再也不会跳出烦恼的对话框了.

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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