免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5280 | 回复: 18

if判断中为0依然执行 [复制链接]

论坛徽章:
1
白羊座
日期:2013-09-18 22:02:26
发表于 2012-04-17 19:48 |显示全部楼层
http://bbs.chinaunix.net/thread-3691227-1-1.html

这个帖子直说ptr->age的core问题;

仔细看会发现if (ptr->name)这句没有coredump,并且输出了if中的一句,但是输出来是ptr->name:0,
按理说ptr->name为0是不应该执行if内的语句的。


第一个问题,为什么ptr->name为0,还是执行了if中的语句?

第二个问题,为什么ptr->name不coredump,而ptr->age就coredump了?

第三个问题,我记得linux里面有offsetof宏,根据offsetof的展开可以得到
             (unsigned int)(&(student *)0->age)
             这样就有不会coredump了,为啥呢?

论坛徽章:
0
发表于 2012-04-17 19:57 |显示全部楼层
编译器只保证程序正确(符合其规范)的结果,至于程序不对应该怎么处理,鬼才知道。

论坛徽章:
0
发表于 2012-04-17 19:58 |显示全部楼层
回复 1# file3


为什么我这边没有“if (ptr->name)这句没有coredump”你说的。
  1. #include <stdio.h>
  2. #include <strings.h>

  3. typedef struct stu
  4. {
  5.     char name[20];
  6.     int age;
  7.     char sex;
  8. } student;

  9. int main()
  10. {
  11.     student *ptr;
  12.     ptr = NULL;
  13.    
  14.     if (ptr->name)
  15.     {
  16.         printf("ptr->name:%d\n",ptr->name);
  17.     }
  18.     else
  19.     {
  20.         printf("nil\n");
  21.     }
  22.    
  23.     return 0;
  24. }
复制代码
而是nil。贴出你的gcc -v和uname -a

论坛徽章:
0
发表于 2012-04-17 19:59 |显示全部楼层
为什么ptr->name不coredump,而ptr->age就coredump

访问null地址本身不会有问题,只读访问。但是写就会有问题,这里会有一个cpu中断产生,给一个core

论坛徽章:
0
发表于 2012-04-17 20:00 |显示全部楼层
我记得linux里面有offsetof宏,根据offsetof的展开可以得到

我们当初写操作系统的时候也大量使用这个技巧来获取变量偏移,比如c实现泛型的list等。大量用这个

论坛徽章:
1
白羊座
日期:2013-09-18 22:02:26
发表于 2012-04-17 20:07 |显示全部楼层
那么 为什么(unsigned int)(&(student *)0->age)不coredump呢?

论坛徽章:
0
发表于 2012-04-17 20:22 |显示全部楼层
回复 6# file3
  1. #include <stdio.h>
  2. #include <strings.h>

  3. /* #define toffsetof(st, m) ((size_t) ( (char *)&((st *)0)->m - (char *)0 )) */

  4. typedef struct stu
  5. {
  6.     char name[20];
  7.     int age;
  8.     char sex;
  9. } student;

  10. int main()
  11. {
  12.     student *ptr;
  13.     ptr = NULL;
  14.    
  15.     printf("%x\n", (unsigned int)(&((student*)0)->name));
  16.     printf("%x\n", (unsigned int)(&((student*)0)->age));
  17.     printf("%x\n", (unsigned int)(&((student*)0)->sex));
  18.    
  19.     /* core */
  20.     *(&((student*)0)->age) = 1;
  21.    
  22.     if (ptr->name)
  23.     {
  24.         printf("ptr->name:%d\n",ptr->name);
  25.     }
  26.     else
  27.     {
  28.         printf("nil\n");
  29.     }
  30.    
  31.     return 0;
  32. }
复制代码
我跟你说了,对0地址的读操作是不会触发一个中断,也可以是cpu操作系统例外,而写就会。所以上面代码中core注释那里就是一个写操作,会触发core。

offset一般是用来算偏移,从而直接获取struct成员位置。只要用基址加上offset出来的偏移就是成员地址。但是这里有其他问题,比如编译器的优化重排等等。

论坛徽章:
0
发表于 2012-04-17 20:25 |显示全部楼层
0地址其实读写本来不是一个重要的问题,产生core本身也不是一件本身就存在的事情,之所以产生core,是程序在访问例外地址的时候有一个cpu中断,交给操作系统,操作系统给一个产生core的信号。对于实地址,理论上你可以直接读写0地址。当然,这里还有很多问题,有些内存布局需要给特定的中断表和设备占用,总之其间比较复杂。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
发表于 2012-04-17 20:48 |显示全部楼层
那啥……原帖两份代码的if测试都成功了?

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
发表于 2012-04-17 21:15 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP