今天在调试一段程序,输出结果总是错误,不知道什么原因,代码如下:
本来以为程序会输出:
可是却大出所料,输出的结果为:
非常奇怪,故把代码修改为以下,以作测试:
输出还是非常奇特:
非常不解,难道是oss的问题还是其他?于是把代码修改如下:
此时,程序奇怪的输出了我想要的结果:
通过以上输出结果,我大致猜到了原因,此时在源码中添加以下代码:
正如我所料,程序输出:
此时可以确定了我的猜测:
oss << inet_ntoa(addr1) << "|" << inet_ntoa(addr2);在运行的时候,首先执行inet_ntoa(addr2),得到一个函数指针,假设是p1;然后执行inet_ntoa(addr1),得到另一个指针,假设是p2,然后整个语句执行oss << p1 << "|" << p2;得到最后结果。问题就在这里,其实p1, p2的值是相等的,也就是说,他们指向同一块内存地址,而该段地址空间内存放的数据为最后一次执行inet_ntoa()时的结果。在加上oss语句是从右向左开始执行的,于是,在执行oss << p1 << "|" << p2;的时候,其实是执行了:oss << p1 << "|" << p1;于是oss中便存放了两个相同的IP地址。
细想一下,系统开发者这样设计也有他自己的道理。由于inet_ntoa()函数调用是不需要用户手动分配内存空间的,这样系统就必须为这个操作分配足够的空间。如果每一次执行该函数都分配一次空间,而用户又没有释放,或者系统释放了一次,然后用户又释放一次,这样都会产生内存泄漏。所以,干脆开发者便开辟一段内存空间,每次调用都使用相同内存,在进程结束的时候由系统收回内存,如此既不浪费,也不需要用户作繁琐的操作。
但是还有一个问题,如果用户手动对该内存段进行释放,也会出现问题,所以建议大家不要使用类似函数,而使用用户可以自定义内存地址的函数,而在这里,inet_ntoa()函数对应的函数则为inet_ntop()。