正文

c中的陷阱2006-09-25 11:08:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/yuqiexing/18791.html

分享到:

先看个题目:void fun(char *p1){p1=p1+1;}main(){char *p="abcd";fun(p);cout<<*p;}这个题目看起来非常简单,但对于初学者来说却是个巨大的陷阱.很多初学者在学习c的时候就会听老师说过:指针是可以用来传值,甚至可以不要return;这句话本身没有错误,错的是初学者的理解!首先说一下答案:结果是a不是b这也许出乎你的意料.但是仔细一想就明白了.首先定义了一个字符型指针p,让它指向一个字符串的首地址,如果没有fun函数,那么*p='a';但是现在调用了fun,难道对p没有影响?是的.调用fun的时候,会将p的值传给p1,也就是说现在p1也指向这个字符串的首地址了.然后执行:p1=p1+1;这样p1会指向下一个字符,也就是'b',但是p还是指向首字符!!!所以结果也就出来了.这时候你可能会怀疑你以前学的指针是不是出现了问题.再来看这个题目,你就明白了:void fun(char *p1){*p1=*p1+2;}主函数不变,结果是'c'(a+2),同样p1开始指向了首地址,就当作一个箱子,然后把箱子里的东西换了(*p1),等调用结束以后,下个人(主函数)再来看的时候,箱子里的东西已经变化了!总之,希望初学者在学习的时候多加琢磨一些关键的话语,这对你的分析能力是很有帮助的.2.main(){char p[]={'a','b','c'};char q[]="abc";printf("%d,%d,%d,%d",strlen(p),strlen(q),sizeof(p),sizeof(q));}感兴趣的读者,你能在不上机的情况下说出结果吗?答案 是3,3,3,4. 我们知道strlen测的 是字符串的实际长度,不包括'\0',而sizeof测的是开始分配的空间.对于char q[]="abc";实际上应该是q[4],而对于char p[]={'a','b','c'};这种写法在很多C语言书上是不允许的,因为没有结束符.所以它的结果可能会出乎意料.在此不多作申明.不过如果写成char p[]={'a','b','c','\0'};那么sizeof(p)=4 3.new的问题 初学者都知道new是用来动态分配空间的,可以不用初始化,而直接赋值.如: int *p=new int; *p=5;//ok 但是 int *p;//只是一个地址变量,并不知道所指的空间 *p=5;//error 除了这些之外,你还知道关于它的什么吗?可能你还知道要释放. 那不释放会出现什么呢? 在<<c++程序设计教程>>(钱能著)的第14章有段很重要的话: "c++程序的内存格局通常有4个区, 全局代码区 代码区 栈区 堆区 全局变量,静态数据,常量存放在全局数据区,所有类成员函数和非成员函数代码存放在代码区,为运行函数而分配的局部变量,函数参数,返回数据,返回地址,等存放在栈区,余下的空间都被作为堆区." 也就是说我们用new创建的空间是分配在堆区了,那堆区有什么性质呢? "操作堆内存时,如果分配了内存,就有责任回收它,否则运行的程序会造成内存泄漏.但是在栈区,只有局部对象退出了作用域,系统自动回收.注意,对于类而言,堆对象的作用域是整个程序生命期,除非调用了delete,否则就不调用其析构函数." 如此说来,如果不用delete释放内存,就会造成内存泄漏,问题可就大了,但是有的时候并不是刚用new创建就要求析构.它的好处就是和整个程序同生命周期,那这样只要你保存了内存地址,就可以随时访问了. 最后再DELETE也不迟. 下面举出一个在MFC中非常经典的例子: 创建模态窗口与非模态是不同的,前者通常用如下代码: Cmydlg dlg; dlg.Domodal(); 有人担心dlg是局部对象会被析构,并非如此,在执行到domodal时,程序会暂停执行,等待执行结果,传值给domodal,不过这里不是我要讲的主题. 再看看非模态窗口的创建过程: (1)Cmydlg dlg; dlg.Create(..); dlg.ShowWindow(); 这样的创建程序是会出错的,因为dlg获得是栈上内存,会自动析构,那关联的资源就没了. (2)Cmydlg *dlg=new Cmydlg; dlg->Create(..); dlg->ShowWindow(); 这种就是对的了.因为此时分配的是堆上内存,生命期为整个程序,所以不用担心内存被回收,也就不用担心窗口会显示不出了. 当然如果关闭了对话框那么这段内存就要回收了,可以用下面的代码: void CMydlg::PostNcDestroy() { delete this; } 意思就是关闭对话框后回收内存. ---------待续  

阅读(4314) | 评论(1)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册