写在前面的话:虽然这段代码中对于指针的使用是不正确的,但是我却在这个不正确的代码中发现了另一个错误,而且深感迷惑,所以打算将此博文推到首页,请各位帮忙回答个问题。
在项目中用到了以下一段代码,执行结果有点奇怪,还没有想明白为什么会这样子
是在网络编程中用到的,因为需要根据新加入的用户IP和已经存在的用户列表中的用户IP进行比对,来判定该用户是否已经存在,所以就使用了上述办法,但是执行结果出人意料,因为if(0 == strcmp(newIp, oldIp))这行代码永远为真,为什么呢?
自己就跟踪代码调试,结果当执行过第二个红线那一行之后,newIp的值也发生了改变,而且newIp和oldIp指向的地址是一样的,为什么这样子呢?
我的猜测是,由于inet_ntoa函数的执行过程会做一些我们不知道的事情,它的功能是将u_long的数据转换为字符串表示的点分十进制Ip地址,但是转换过之后这个Ip地址存储在哪里呢?我认为,它应该是开辟了一个存储空间来存放这个字符串,接着第二次执行这个函数的时候也是如此做的,而且使用的存储空间是同一个存储空间,所以才造成了现在这种情况。
于是我就修改了一下代码,给newIp分配一个存储空间,将inet_ntoa的结果放到这个存储空间中去,这样代码就按照自己的思路正确的执行了。下面是修改后的代码:
犯这样的错误,或许对于一个新手来说很正常,总的来说,还是使用指针的时候要小心,否则就会出现一些意料之外的诡异事件。。。
不过我还是有个小疑问,两次使用inet_ntoa结果得到的存储空间地址是相同的,这是个巧合还是必然会发生的呢?我的想法是调用这个函数,它会自动分配一个空间来存储,但是立刻就销毁了,而值还存在那里,第二次使用还是随机分配,地址相同只不过是因为分配空间的算法认为刚才那个空间是可用的,所以就将此空间又分配给它了,所以,我认为这是个巧合,如果两个函数离的比较远,也就是说它们之间还有别的函数需要动态分配空间,那么它们的值就不会一样了。
下面是两次的执行结果:
事实胜于雄辩,看着调试的代码,我发现自己的猜测是错的,我在两次函数调用中间利用new分配了一块存储空间,结果p1和p2的值还是一样的。我迷惑了,难道这个函数每次都用一样的地址么?不可能吧。。。
于是我继续做下面的测试,在另外一个函数中使用该函数inet_ntoa,执行结果如下:
第一个函数中:
第二个函数中:
好吧,看到它们的地址,我彻底的迷惑了,我的猜测确实是错的,可是还是那个问题,为什么这个函数每次执行分配的存储空间都一样呢?
虽然还是带着自己的疑问结束了这个博客,但是也学到了很多的东西,遇到问题按着自己的思路去思考就好了,没必要一遇到问题就上网上搜去,当然我也不反对上网找资料,但是现在的现象是往往很多问题在网上都是重复的,搜来搜去都是一样,从这个网站转到另一个网站,而且这样的答案对自己的问题还没有什么价值。
我认为遇到问题,首先应该自己去思考解决思路,不要怕困难,其实当你真正的去做的时候才会发现并不是那么困难,而且这样更可以增加自己技术的增长,怎么说呢,我认为抄来的东西还是没有自己琢磨出来的知识让自己印象更深刻。
后面这段话可能不太符合某些人的观点,那么请保持绅士风度,因为我们应该让我们听到不同的声音,这样我们才能知道跟自己不同的观点。
谢谢这评论中两位的回答,我总结以下问题的答案,就是这个函数会把执行结果放在一个静态存储区,它保证在同一线程中下一次执行Socket函数之前,数据是有效的,所以,我们应该在下次执行Socket函数之前将数据拷贝出来。这里我只是保存了它的指针,所以,在下次执行此函数时,数据被覆盖了。
详见百度百科:inet_ntoa()
图片: