© / Posted in 知识如海 / September 8, 2009
如下两个函数,都是返回一个局部变量,但是在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;
}
五大内存分区
在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。
堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改
上面是别人的一个描述,其实好像没分那么多“区”。不过也记不清了,呵呵~~基础知识不牢靠啊~~
今天碰到个局部变量new的问题~~于是乎找到了以上的一个局部变量例子。然后再由以上的内存分区说法。综合一下。局部变量也就差不多这些了吧。
然后我碰到的问题,引用不知道是谁的名言——谁污染谁治理。就算是在函数内new的局部变量,也要秉着谁污染谁治理的原则,谁TNND分配的就给我释放。呵呵,虽然不一定会有问题,但是这是个编程习惯问题。自己的屁股自己擦。
在函数里new的内存,要自己delete掉,如果碰到像我今天一样,需要把new出来的指针返回的话。一种办法是把函数返回的指针用完后delete掉,不过不是正规的,正规做法应该是在函数外new,然后通过参数传入指针,然后再在函数内写。最后,用完了,把函数外new的东西释放掉。
当然,各人有各人的编程习惯,呵呵~~
上一篇:const char * 转换为 char * | 下一篇:牛人啊——猥亵男
总觉得你的例子和你的题目不是很相符啊。
而且例子中的两个函数都是“不规范”的,我的意思是,这样写虽然没有语法错误,但是编译的结果是“不可预料的”。
GetMemory1 中返回的指针指向一个常量,常量在函数中定义,那常量又在哪个“区”呢?
GetMemory2 是肯定有问题的,因为它一返回,p 就被释放了。
有空交流下。
@Euyuil, 呵呵,那两个本来就是有问题的例子,引出话题而已~~可能是我没表述清楚吧~~
GetMemory1 存储于常量区,程序结束后才释放~~所以,返回后使用的话,指针还有效~~
GetMemory2就是开头第一件话说的一个打印乱码了,因为内存已经释放了~~
虽然都不规范,但是GetMemory1的写法,在不得以的情况下,还是可以的,不过还是会有隐藏的问题,所以,我说了,谁污染谁治理,谁分配的空间,谁释放掉。
嗯。其实我编程的时候关于内存的创建和释放是比较守规矩的。我也没有想过尝试编写和编译这样的代码……
@Euyuil, 嘿嘿,我就不行了,我经常就是实现功能就行,所以写的代码……惨不忍睹
而且我很喜欢写“面向对象”的代码,呵呵~
我经常为了给一个函数或者对象或者类起名而思考较长一段时间。
@Euyuil, 呵呵~~能享受写代码的乐趣是件很不错的事~~