tags: C Network Debug
问题
今天看了一下网络编程, 发现其中有一个接口函数很有意思, 就是从二进制转换到点分十进制表示的IP地址 的函数inet_ntoa()
, 直接使用倒是没什么异样, 但是下面一个例子却出现了一个很有趣的现象:
这个例子是引用TCP/IP网络编程
这本书上的, 可以看出第二次调用inet_ntoa()
时候并没有将返回值赋值给变量str_ptr
, 但是输出这个变量的时候还是发生了改变, 这是为什么呢?
书中给出的解释是:
该两数将通过参数传入的整数型地址转换为字符串格式并返回。但调用时需小心,返回值
类型为char
指针。返回宇符串地址意味着字符串已保存到内存空间,但该函数未向程序员要求分
配内存,而是在内部申请了内存并保存了宇符串。也就是说,调用完该函数后,应立即将字符串
信息复制到其他内存空间。因为,若再次调用inet_ntoa
函数.则有可能覆盖之前保存的字符串信
息。总之,再次调用inet_ntoa
函数前返回的宇符串地址值是有效的。若需要长期保存,则应将字
符串复制到其他内存空间。
也就是说, 其内部会首先分配一段空间, 用来保存转换后的字符串, 所以第二次调用的时候虽然没赋值给str_ptr
, 但是该变量仍能获取到这个值(通过指针).
通过查看man inet_ntoa
发现:
The string returned by inet_ntoa() resides in a static memory area.
inet_ntoa()返回的字符串驻留在静态内存区域。
这就是说其内部分配的是一份静态变量, 所以才导致了上述问题出现.
例子
下面来看一个我自己写的例子:
乍一看大家可能以为结果会是123123
, 因为第二次调用并没有改变p
的值, 但是由于在函数f1()
的char pp[20]
变量前面加上了static
, 使pp[20]
成为静态变量, 这就保存在全局变量区了, 在f1
函数结束之后变量也不会销毁, 所以才能由指针p
去获取一个新得到的值, 从而可以不赋值就能改值了.