C++是促进脑死亡的最佳方式

一个老程序员坐在这个角落,看眼前人来人往。

对任何返回指针的函数保持慎重

搞怪的调试,IP地址输出总是错误的问题。检查日志发现了一个日志中间的IP地址总是输出错误。

<?xml:namespace prefix = o />

 

 

Dec 28 11:08:30.759 2007@LM_INFO@Listen peer [124.115.1.80|80] accept Socket IP Address:[124.115.1.80|64119] Success.

Dec 28 11:08:31.463 2007@LM_INFO@Listen peer [124.115.1.80|80] accept Socket IP Address:[124.115.1.80|1416] Success.

Dec 28 11:08:37.942 2007@LM_INFO@Listen peer [124.115.1.80|80] accept Socket IP Address:[124.115.1.80|31580] Success.

每次后面的地址总是输出错误,没有将远端地址正确显示出来,每次远端地址显示的都是本地地址。

检查日志输出的地方,代码很简单。

    ACE_DEBUG((LM_INFO,"Listen peer [%s|%u] accept Socket IP Address:[%s|%u] Success. /n",

        local_address_.get_host_addr(),

        local_address_.get_port_number(),

        remote_address_.get_host_addr(),

        remote_address_.get_port_number()));

先怀疑栈被破坏,检视了代码半天,觉得没有问题,在Windows下调试,

发现问题依旧,跟踪进函数堆栈,发现ACE_DEBUG 调用函数内部2个参数的地址居然一样,抓狂。

甚至怀疑ACE的代码有问题,研究了半天ACE的变参函数的写法。(也好,终于明白了变参函数怎么写)

一次无意的跟踪到了ACE_INET_Addr get_host_addr()内部,发现了其使用的是C函数inet_ntoa,恍然大悟。

丑陋的C语言,当年为了图省事,相当的函数使用了static 成员作为函数的返回值。

这个方法在大大的方便了使用者的同时,也给使用者带来了重大的危险,使用不慎就会导致莫名的bug

对于上面的例子来说,由于是变参函数,参数的传递顺序是从右到左。所以local_address_.get_host_addr()后入栈,所以每次返回的地址都是他的数值。

教训:

1. 永远不要做这种将指针作为函数返回值的事情。这种方式在任何重入的地方都是不安全的

2.对于别人的返回的指针也慎重使用。

阅读更多
文章标签: socket windows 语言 c
想对作者说点什么? 我来说一句

C语言指针讲解

2013年12月10日 1.44MB 下载

C语言指针总结

2012年03月11日 40KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭