求助:关于局部变量的一道面试题
如下两个函数,都是返回一个局部变量,但是在main函数里打印的时候一个打印出“hello world”,一个打印出乱码,为什么?
#include <iostream.h>
char *GetMemory1()
{
char *p="hello world";
return p;
}
char *GetMemory2()
{
char p[]="hello world";
return p;
}
void main()
{
char *str1 = NULL;
char *str2 = NULL;
str1 = GetMemory1();
str2 = GetMemory2();
cout<<str1<<endl<<str2<<endl;
}
问题点数:20、回复次数:26Top
1 楼sinall()回复于 2006-08-30 15:52:29 得分 0
char *p="hello world";
存在全局数据区
char p[]="hello world";
存在栈区Top
2 楼zdl1016(【不要给我分,以免影响我性欲】)回复于 2006-08-30 16:14:03 得分 10
char *p="hello world";//字符串存于常量区,程序结束时由系统回收
char p[]="hello world";//存于栈上,出了函数便销毁
建议楼主细细读下我以前的一下帖子,和你是一样的问题
http://community.csdn.net/Expert/topic/4963/4963399.xml?temp=.5352594Top
3 楼zdl1016(【不要给我分,以免影响我性欲】)回复于 2006-08-30 16:15:24 得分 0
五大内存分区
在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。
堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改
Top
4 楼neoadane(乌云)回复于 2006-08-30 16:20:40 得分 0
char *p="hello world";
存在全局数据区
char p[]="hello world";
存在栈区
-------------------
为什么??Top
5 楼jixingzhong(瞌睡虫·星辰)回复于 2006-08-30 16:24:08 得分 0
呵呵 , 一种标准定义而已 ...
你说 定义字符串为什么用的是 char ? 不是 dog 或者 fish ?
规定而已,语言规定了关键字是 char 而不是 别的,
没有理由 ...Top
6 楼kingbo2006(韫知)回复于 2006-08-30 16:46:24 得分 3
char *p="hello world";
采用的是堆分配,在离开函数后,分配的空间并没有得到释放,因此指针地址仍然有效。
而char p[]="hello world";是在函数中定义了一个字符数组,在离开函数以后,为数组分配的空间,就被释放了,因此P的地址是不确定的,所以不能得到正确的结果。
Top
7 楼neoadane(乌云)回复于 2006-08-30 17:03:58 得分 0
谢谢zdl1016(探路者),看了你的帖子学到了东西。 kingbo2006(韫知) 你的说法不对,建议你也看看zdl1016(探路者)那篇帖子。
jixingzhong(瞌睡虫:选择了远方,只顾风雨兼程!) ,我说的为什么是说为什么char *p="hello world";存在全局数据区,我的错误在于没有没注意"hello world"是字符串常量。Top
8 楼neoadane(乌云)回复于 2006-08-30 17:06:26 得分 0
晚上给分Top
9 楼kulv0405(疯疯进步)回复于 2006-08-30 17:20:09 得分 0
有道理 学习Top
10 楼lbaba(翔)回复于 2006-08-30 17:29:53 得分 5
LZ....你又错了......
看完我说的再给分......
zdl1016(探路者),kingbo2006(韫知) 这两位仁兄都没有说错.......
只是都没有说得够清楚而已.......
char *p="hello world";
这句是声音一个指针,并初始化它指向一块常量的区域.正如上面两位仁兄所说的常量是分配在堆上,函数退出了这块内存区域并没有被释放..所以可用它的返回值来引用这块区域..
char p[]="hello world";
而这句和上面那句有很大的差异...编译器帮我们做了一些工作..具体如下:
1.先分配足够大的内存给数组p(这里要12个字节).(注意数组p是局部变量,所以它是分配在栈上)
2.把"hello world"copy到上面那段内存中.
呵呵...下面就好解释了....一出了这个函数........
呵呵...不过还要提醒一下楼主....其实上面这两个函数的返回结果也是有可能相同的...
你要明白释放内存...并不是把它改写...而只是把它的控制权交给了系统而已......
..呵呵...记住哦..上面两位仁兄都没有说错...要给分可就不能只给一个,,一个不给哈...Top
11 楼Arthur_()回复于 2006-08-30 18:30:09 得分 0
补充一点,给我也加分Top
12 楼hziee_()回复于 2006-08-30 19:53:50 得分 0
妈的,又时林锐的笔记。各位公司老大,笔试题目能不能又新意点Top
13 楼neoadane(乌云)回复于 2006-08-31 10:44:28 得分 0
to:lbaba(翔)
char *p="hello world";
这句是声音一个指针,并初始化它指向一块常量的区域.正如上面两位仁兄所说的常量是分配在堆上,函数退出了这块内存区域并没有被释放..所以可用它的返回值来引用这块区域..
-----------------------------------------
我又糊涂了,常量应该是分配在常量存储区,而不是堆吧?堆上是由new或者malloc分配的。
昨晚没上网,今天给分,呵呵。Top
14 楼superyys(无血野人)回复于 2006-08-31 14:37:49 得分 0
char *p="hello world";
应该是分配在堆上,等效于
char *p=new char(15);
strcpy(p,"hello world");Top
15 楼CapRobbie()回复于 2006-08-31 15:35:04 得分 0
这个题我用vs05会都输出"hello world"呵呵
猜测是因为栈指针移动后内容并未修改Top
16 楼bingxiecs(恋雨天蝎)回复于 2006-08-31 16:34:55 得分 0
妈的,又时林锐的笔记。各位公司老大,笔试题目能不能又新意点
别骂,我要不是看了现在还没找到工作呢!虽然我很菜,但是我会很努力的!Top
17 楼junku_kong(I ganna fly, so I can fly)回复于 2006-08-31 17:12:10 得分 0
学习中Top
18 楼einsnabuck(撒旦化身)回复于 2006-08-31 17:21:25 得分 0
to zdl1016(探路者)
不知道在C语言中,自由存储区和堆有什么区别呢?好像在C语言里,malloc和free也是在堆申请的.Top
19 楼zdl1016(【不要给我分,以免影响我性欲】)回复于 2006-08-31 17:29:53 得分 0
to superyys(无血野人):
可别误导初学者呀.
//1
char *p="hello world";
//2
char *p=new char(15);
strcpy(p,"hello world");
1与2不等价.因为
//3
char *p="hello world";
*(p+2)='d'; //执行出错,因为字符串分配在常量区,不能修改;程序执行进会崩kui.
//4
char *p=new char(15);
strcpy(p,"hello world");
*(p+2)='d'; //正常
cout<<p<<endl;
我是在VC6.0下试的.Top
20 楼xyx119(小菜)回复于 2006-08-31 17:53:18 得分 2
楼上的厉害,实践出真知!
嘿嘿!我来总给一下!
char *p="hello world";
在常量存储区
char p[]="hello world";
在栈存储区
Top
21 楼blue_zyb()回复于 2006-08-31 18:34:23 得分 0
To:zdl1016(探路者)
char *p=new char(15);
strcpy(p,"hello world");
*(p+2)='d';
==============================
厄,笔误吧,应该是char *p = new char[15]Top
22 楼neoadane(乌云)回复于 2006-08-31 19:43:58 得分 0
zdl1016(探路者)说得很对,我差点又被迷糊了。。。
给分!!Top
23 楼jianj03()回复于 2006-09-01 08:35:15 得分 0
char *p="hello world";
在常量存储区
char p[]="hello world";
在栈存储区
栈区在函数返回时就回收了,常量区是不可以改变的,所以返回后对栈区的引用是乱码。Top
24 楼Nowish(看我能忍耐多久)回复于 2006-09-01 09:24:06 得分 0
关注~Top
25 楼lmlmlmnew()回复于 2006-09-01 10:24:12 得分 0
5大内存分区呢??
静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。
栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
堆区:亦称动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在适当的时候用free或delete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存。 但是,良好的编程习惯是:如果某动态内存不再使用,需要将其释放掉,否则,我们认为发生了内存泄漏现象。Top
26 楼brookqdc(小溪)回复于 2006-11-01 21:52:32 得分 0
markTop




