michael175 发表于 2008-2-24 00:37

有请编程高手指导下!!!

#include <iostream.h>
char *f()
{
char s[]="HELLO";
return s;
}
char *f1()
{
char *p=NULL;
char s[]="world";
p=s;
return p;
}
int *f2()
{
int *p;
int i = 32;
p = &i;
return p;
}

void main()
{
   cout <<<< endl;
   cout <<f1() << endl;
   cout << f2() << endl;
}
该程序的输出结果是f(),f1()输出乱码,f2()输出内存地址。


改动下程序
#include <iostream.h>
char *f()
{
char s[]="HELLO";
return s;
}
char *f1()
{
char *p=NULL;
char s[]="world";
p=s;
return p;
}
int *f2()
{
int *p;
int i = 32;
p = &i;
return p;
}

void main()
{
   cout << *f() << endl;
   cout <<*f1() << endl;
   cout << *f2() << endl;
}
输出结果是 H
                   W
                   32


哪位高手可以解释下原因????????????

轻水惜寒 发表于 2008-2-24 12:42

应该是返回值的类型与其所在函数类型的关系问题

onttpi 发表于 2008-2-24 12:58

f2()中返回的是临时变量的指针
这个也许在不同的编译器不同的系统有不同的结果?
个人觉得三个函数都不安全

Leon001 发表于 2008-2-24 13:39

函数也是内存地址,看作指针,f()、f1()返回的是内存地址,但是该地址要转变为char型,不一定可转为可见字符及有意义字符,故是乱码,而f2()的转为int型,故是地址(数字)。

*f()、*f1()、*f2()则为指针指向内容,因此可输出H、W、32。

菜鸟看法,望版主众人指正。共同进步。

onttpi 发表于 2008-2-24 13:51

#include
char *f1()
{
char *p=NULL;
char s[]="world";
p=s;
std::cout<<&p<<std::endl;
return p;
}
int main(){
std::cout<<f1()<<std::endl;
std::cout<<(int)f1()<<std::endl;
}受教了,THX LS

[ 本帖最后由 onttpi 于 2008-2-24 13:56 编辑 ]

onttpi 发表于 2008-2-24 13:58

突然想起以前看过的东西,有兴趣的猜猜输出是:std::cout<<'A'<<'AA'<<std:endl;注意,两个都是单引号...

onttpi 发表于 2008-2-24 14:05

LZ的代码用printf("%p",f1());会有不同的结果..
printf VS cout..

Leon001 发表于 2008-2-24 14:15

cout用了运算符重载,可以说是比较“智能”的,无须像printf指定类型……

刚开始看C++ Primer

hjack 发表于 2008-2-24 14:16

char s[]="HELLO"; 这样声明的变量是在堆栈区里的.当函数调用结束后(执行完return s;),该指针所指的内存单元将会被释放,这个函数是有隐患的.

gyCai 发表于 2008-2-24 14:50

我觉得cout输出串指针导致的问题吧。
cout输入串指针也是按照是否\0来判断结束的,返回的指针是指向首地址,在下个cout之前,无法获取到\0,所以输出乱码。
还有,楼上的char s[]="HELLO"应该是在静态存储区的吧?在程序结束前都不会自动释放。

hjack 发表于 2008-2-24 22:41

静态区需要const来声明吧....

powerwind 发表于 2008-2-25 09:21

静态区需要static来声明吧....

gyCai 发表于 2008-2-25 10:55

是我搞错,char *ptr="hello"是静态,char s[]="hello"是堆栈。

gyCai 发表于 2008-2-25 17:02

我觉得4楼说得不准确,指针只有分指向某种类型的指针,指针本身严格来说不属于任何一种类型。

iptton 发表于 2008-2-25 17:07

指整应该就是一个内存地址吧?或者说指针本质上是一个数?

gyCai 发表于 2008-2-26 14:31

说指针本身是个数没错,因为是变量的值不外乎也就是内存位置所存储的值,指针也一样。但是也不能把指针跟数等同,因为它不完全支持数的运算啊。

kpkp 发表于 2008-3-8 22:08

我是搞嵌入式的 对该问题有些看法 特来吹吹牛

首先这里涉及的堆(heap)和栈(stack)的概念

在一个函数内如果静态分配内存 就是像这里的 char s[]="HELLO";
是在该函数的stack中分配 生命周期只在该函数范围内 一旦函数返回 变量就失去意义的
同时由于在嵌入式系统中 函数的栈通常比较小 所以如果分配比较大的内存 就需要在heap中动态分配 如
char* longString = (char*)malloc(MAX); // MAX的值比较大
同时可以把该指针返回
return longString;
后在main函数可以继续使用

像上面那样即使能够输出正确的返回值也是不安全的 最常见的bug就是会出现内存泄露

。。。。。。。。。。。
就当我是吹牛吧

[ 本帖最后由 kpkp 于 2008-3-8 22:46 编辑 ]

iptton 发表于 2008-3-9 00:57

LS的是观点 3F 9F都有说了
欢迎常过来“吹牛”

jinry 发表于 2008-3-9 16:50

原来我不懂....

aauutthh 发表于 2008-3-15 17:08

17楼的仁兄说的非常正确
不必要太谦虚
不管是C调用还是STD调用,都在函数调用时在栈区分配合适的内存,作为存储和运行的空间.
所以当函数返回时,虽然返回的指针值没有变,但是指针所指向的数据已经被POP掉了,也就是指向了内容不明的地址了.
这方面内容要搞清楚,建议读一读汇编的书,专门看"汇编与C的混合编程"还有函数调用规则.
页: [1] 2
查看完整版本: 有请编程高手指导下!!!