Chinaunix首页 | 论坛 | 博客
  • 博客访问: 229744
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 296
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-22 11:52
文章分类

全部博文(31)

文章存档

2018年(3)

2017年(11)

2016年(12)

2015年(5)

我的朋友

分类: C/C++

2016-07-12 17:45:28

最近在写应用层的c代码,发现以下代码的诡异之处:
#include
#include
#include
#include

int main(int argc ,char ** argv){
     struct in_addr addr1;
     struct in_addr addr2;
     struct in_addr addr3;
     inet_aton("192.168.10.3",&addr1);
     inet_aton("193.168.10.3",&addr2);
     inet_aton("194.168.10.3",&addr3);

     printf("addr1:%p addr2:%p addr3:%p\n",inet_ntoa(addr1),inet_ntoa(addr2),inet_ntoa(addr3));
     printf("addr1:%p ",inet_ntoa(addr1));
     printf("addr2:%p ",inet_ntoa(addr2));
     printf("addr3:%p \n",inet_ntoa(addr3));
     return 0;
}

第一个printf 居然和后三个printf的输出结果不一样,做各种测试,只能确定是inet_ntoa的问题,具体什么原因不明
第一个的结果是,三个地址都是192.168.10.3,后三个的跟预期一样。
无奈,只好去请教以前的同事,前老大果然牛,一看就知道问题在哪里了,原来是printf 压栈顺序和inet_ntoa 函数的实现
造成的,因为inet_ntoa 是用一个静态的内存返回的,所以每次调用inet_ntoa函数返回值的指针是地址是一样的,而printf的
压栈顺序是从右到左的,就是说inet_ntoa(addr1)是最后计算的,并赋值给inet_ntoa的这个函数使用的这个静态内存的,因此
输出的时候,就变成都是一样的了。返回指针还是用函数参数去取比较好,别用返回值,用返回值的话,都不知道是该调用者
管理呢,还是实现者管理这个指针。inet_pton 好像就不会有这样的问题,因为它是用参数去取的
ps : printf 分两步走,压栈(就是计算), 输出

使用inet_ntoa和inet_ntop 这两个函数的时候没有引用头文件arpa/inet.h ,编译不报错,但是会出现以下两个问题
1).这两个函数的返回值与NULL 比较,会提示comparison between pointer and integer 的warning ,其实这里就暗示了没
有申明(函数没有申明默认返回int)
2).直接%s打印这两个函数的返回值会出现segment fault,打印inet_ntop传进去的dst 参数,得不到正确地址
加上头文件arpa/inet.h 就没有问题了,只是觉得编译居然不报错,据说在32位的机器上不加头文件也没有问题,
只是在64位的机器上会出现(没有验证过)
阅读(1848) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~