最近看linux程序设计,对0地址的读取被搞糊涂了!
两段源码:
1:
#include
#include
#include
:int main() {
char *s = (char *)0;
printf("A read from null %s\n", s);
exit(EXIT_SUCCESS);
}
输出:A read from null (null)
2:
#include
#include
#include
int main() {
char z = *(const char *)0;
printf("Hello world \n");
exit(EXIT_SUCCESS);
}
输出:段越界!
这是为什么呢?这两段程序的差别也就是1是把零地址赋给指针后,对该指针进行访问,而且这时候怎么就知道零地址上的是null呢而2是直接把零地址上的值赋给变量?不都是对零地址进行访问吗?
我看《linux程序设计》上说:第一个是linux在gnu C函数库的包装下,容忍了读操作。2是直接尝试从零地址上读取数据,而且这和内核之间并没有GNU的libc库的存在,所以被终止!
怎么就1是在gnu C的函数库包装了,2就不是呢?头文件,编译方式都相同的啊,搞不懂啊
大家帮忙解释解释啊!


wucongdonglai 于 2010-11-02 09:20:05发表:
3# deepwhite
恩,应该是很熟的,《linux程序设计》的两个作者好像都是内核维护者,水平肯定差不了,这也的确是拿来做教学用的,要是实际应用中,这种没有把握的东西,打死我也不用的,不然程序一大,调试是要死人的!
wucongdonglai 于 2010-11-02 09:17:35发表:
2# shenhao0129
恩,也只能这么解释了,搞不明白内部机制是怎么样的!哎,还是我水平有限啊
deepwhite 于 2010-11-01 20:21:04发表:
纯教学的教程,这个例子个人感觉没啥意义。
写这个例子的人,要么是对 glibc 很熟,要么就是喜好奇淫巧计。
shenhao0129 于 2010-11-01 17:49:29发表:
我也不是特别的懂,第一个程序中 ” char *s = (char *)0; “ 只是把0这个地址强制转化为指针,然后传给指针s,此时用printf函数输出的时候是应该是printf库函数帮你完成了取值函数,而第二个是你自己取值的,可能系统并不允许你这么做,当然我也只是根据你给出的程序设计上给出的解释重新解释一下而已,具体的内部的机制可能要查阅其他相关资料