关于C语言中的内存保护问题,高手进来讨论,绝对有价值,100分奉送。
假如函数中这样声名一个字符串:
void f(void)
{
char *pStr = "HELLO";
*pStr = 'Y';
......
}
这样会发生什么情况呢?其实编译器编译的时候总是会在代码的静态DATA区创建一个“HELLO”的字符串数据,然后把pStr指针指向这个静态数据区的地址,按理这样的静态数据应该相当于是const的,这个数据区的数据应该是不允许被修改的,属于常量字符串。问题就出来了,后面*pStr = 'Y'这一句,在VC编译下运行会出错,报非法的地址访问,得到正常保护;但是在BorlandC中编译后运行就没有抱错,运行后pStr变成了"YELLO"。
我想问的问题是:
1、VC对这个常量字符串的内存保护的依据是什么,我跟踪了VC的汇编语句,也没有发现什么特殊语法,但是在VC下单步运行到那儿就是要报内存访问非法,从而起到保护作用,不知道VC的保护原理是什么,这种保护是怎么实现的,为何在BorlandC下编译这种保护就没有。
2、同样的,如果在VC下声名了一个const类型的变量,当然如果企图去修改它则预编译的时候就会被发现,但是如果用一个指针指向这个const变量的地址骗过编译器,BorlandC下面就可以间接实现修改这个const的目的,而VC编译后运行就抱错,也就是runtime的时候骗不过去,当然,保护是合理的,但是不知道VC的这种保护是怎么实现的。代码如下:
const char cTest;
char *pTest;
pTest = &cTest;
*pTest = 'A'; //这样间接修改cTest,但是骗不过VC编译后的代码。