最近一直在看Andrew Koening写的书籍,可以说学习C/C++或者从事这方面的开发的人员非常值得一看的书籍,这里我推荐看看《C陷阱与缺陷》与《C/C++沉思录》。
这里先来看看《C陷阱与缺陷》一段代码。
#include <stdio.h> int main() { int i; char c; //printf("i address:%ld/n",&i); //printf("c address:%ld/n",&c); for(i=0 ; i<5; i++) { scanf("%d",&c); printf("%d ",i); } return 0; }
这么精小的一段代码,看看运行结果将会是什么?请看清楚C是字符变量。
刚开始的时候,对他讲的东西不是很明白,为了更加清楚,分析相关内存结构。
由于scanf指向的是一个整形指针,此时C接收字符录入,所以在给C输入数据的数据的时候,会将i的一些内存地址进行覆盖,怎么覆盖的呢?在FC6下,会将i的低端地址覆盖成C的高端地址,不知道这么说能不能明白?就是说C实际接收了一个整形变量,但是C存不下,多出的那部分怎么办呢?就将C的高端地址位覆盖成I的低端地址位了,所以I的值一直都是0,所以在运行此程序是一个死循环状态。
上面注释掉那两段,可以打印看看C与I的地址。我这里打印的地址是连续的。
但是在VC6中,是可以正常运行的,这就是我说的内存地址覆盖方式不一样,换句话说,怎么覆盖是有编译器决定,这里我是这么猜想,VC覆盖内存的时候是C的左彻的那段内存而不覆盖I的内存地址,所以在VC中能正常。
这也是一个猜想,怠于证实。而在FC中是“往右”进行覆盖。
所以开发的时候,一定要注意,这种陷阱一旦走进去的,就很难调试,有时候也有一种“凑巧”来避开这个问题,差错就更加不好查。希望在以后开发的时候能给大家有一定的参考。