• inet_ntoa 陷阱


    前天同事问我一个关于ip被"替换"的问题,代码大概如下:

    ip_ local = networkMgr.GetLocalIP();  //127.0.0.1
    ip_ server = networkMgr.GetServerIP(); //0.0.0.0
    printf("  l:%s",inet_ntoa(local));
    printf("  s:%s \n",inet_ntoa(server));
    
    //network manager to do something
    
    printf("  l:%s s:%s \n",inet_ntoa(networkMgr.GetLocalIP()),inet_ntoa(networkMgr.GetServerIP()));

    /// 输出结果:
    // l:127.0.0.1 s:0.0.0.0
    // l:0.0.0.0 s:0.0.0.0

    "正常情况"下,下边一句应该返回 127.0.0.1 才对.可是为何会发生这种情况? 最初没留意到inet_nota 函数的作用,认为是networkMgr 在处理其他事中改变了本地IP地址导致 networkMgr.GetLocalIP() 获取到新值.熟加数据断点调试(其实不用这么麻烦,直接printf("%u",networkMgr.GetLocalIP()) 便成),发现数据没有被修改。

    想起x进制转换成字符串的函数,其形式是:

    char* itoa (int value, char * str, int base);

    inet_ntoa 函数:

    char* inet_ntoa (struct in_addr);

     与inet_ntoa对比,itoa函数的字符串缓冲由参数提供,而inet_ntoa 只需提供 in_addr结构体便可(也可看成是32位无符号整形),说明inet_ntoa返回的字符串缓冲由内部提供。

    返回的字符串缓冲要么由堆内存申请,需要自己手动释放;要么是返回内部静态缓冲的地址。

    如果是前一种,调用者容易忘记释放内存而做成内存溢出;还有一个问题就是调用者不知道该如何释放,是调用free,还是delete[],还是_aligned_free?这种设计还需提供一个释放内存的接口,明显选择第二种方便快捷简单明了(但需要调用者注意)。

    具体查看API文档:http://msdn.microsoft.com/en-us/library/windows/desktop/ms738564(v=vs.85).aspx

    其实文档中已经说明内部就是返回内部静态缓冲的地址了。当然也可以直接输出来验证:

    char* ls = inet_ntoa(networkMgr.GetLocalIP());
    char* ss = inet_ntoa(networkMgr.GetServerIP());

    printf(
    " l:%p s:%p \n",ls, ss);

    至于为何printf 会输出 “ l:0.0.0.0 s:0.0.0.0” 而不是“ l:127.0.0.1 s:127.0.0.1”,这里可以自行查看函数调用约定以及其入栈顺序。例如 stdcall、cdecl等等。

    补充:调用inet_ntoa 时还需注意多线程安全问题,建议使用 inet_ntop函数代替。

    搜索了下inet_ntoa发现很多人都遇到过类似问题,甚至百度都有大量说明 = =:

    C/C++返回内部静态成员的陷阱 http://blog.csdn.net/haoel/article/details/1388498

    inet_ntoa使用陷阱: http://hi.baidu.com/lovzs/item/cc9529089bb55e37a3332aa5

    inet_ntoa百度百科:http://baike.baidu.com/view/569200.htm

  • 相关阅读:
    手势
    ios提示框,自动消失
    UITableView
    UIAlertView
    微信公众号主页链接
    试用avalon2.0
    VirtualPathProvider的使用
    代码暂存 [获取二唯码并识别保存二唯码]
    提交数据url太长导致提交失败
    打通前后台
  • 原文地址:https://www.cnblogs.com/godzza/p/2957015.html
Copyright © 2020-2023  润新知