2016-06-22 153 views
1

我正在通过关注Beej's Guide to Network Programming文章学习网络编程。有一个例子:在freeaddrinfo上发生了什么事?

bind()
struct addrinfo hints, *servinfo, *p; 

if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) { 
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 
    return 1; 
} 

// loop through all the results and bind to the first we can 
for(p = servinfo; p != NULL; p = p->ai_next) { 
    //socket(...) 
    //bind(...) 
    break; 
} 

freeaddrinfo(servinfo); // all done with this structure 

if (p == NULL) { 
    fprintf(stderr, "server: failed to bind\n"); 
    exit(1); 
} 

后,freeaddrinfo()被调用。我认为servinfo链接列表现在应为NULL,并且指针p应该为NULL,但不是,p不是NULL,代码运行良好。

我想知道为什么在调用freeaddrinfo之后p不为空?

回答

2

在循环之后该指针p要么指向用于成功地创建和绑定套接字,或者这将是NULL如果可以使用没有结构的addrinfo结构。

这个freeaddrinfo在循环和检查之间被调用并不重要,因为你不取消引用变量p,你只检查它是否是空指针。

但是,如果在调用freeaddrinfo后试图取消引用p那么你会尝试访问存储不再分配给你,你将有未定义行为

freeaddrinfo调用不会更改任何变量,它不能。如果分配的指针为malloc,然后用该变量调用free,则它不会将变量设置为NULL,也不会将指向同一内存的任何其他变量设置为NULL。阅读有关的更多信息,按值传递参数以模拟c中的引用,以了解有关原因的更多信息。

+0

是的!是的!指针仍然是指针。即使'* p'也是空的。谢谢! – user1418404

+0

调用'freeaddrinfo()'后''p'不保证为NULL。如果'* p'变为NULL',那么分配内存管理器的副作用就是释放'serveinfo'。有些内存管理器在释放内存时会将内存清零(或者甚至用特殊的值如0xcdcdcdcd或0xbaadfood来帮助调试),但是不能依赖代码中的行为。 –

0

这与使用free时发生的情况没有什么不同 - 指针仍指向相同的地址,但实际内存未分配。这不是一个简单的免费电话的原因是,你实际上已经释放了一系列资源。从手册:

freeaddrinfo()函数释放分配给 动态分配的链表res的内存。