使用 addrinfo 结构进行内存管理

Memory management with `addrinfo` structures

我刚开始使用 C 中的 UDP 套接字,我有一个与内存管理相关的问题。通常示例显示以下内容

struct addrinfo *result;    //to store results
struct addrinfo hints;      //to indicate information we want
:
:
:
if( (s = getaddrinfo(hostname, NULL, &hints, &result)) != 0){
  fprintf(stderr, "getaddrinfo: %s\n",gai_strerror(s));
  exit(1);
}
:
:
:
//free the addrinfo struct
freeaddrinfo(result);

我还看到了在 for 循环中使用的附加本地 addrinfo 结构的引入,以便在 result 中循环以提取特定条目。 .像这样

struct addrinfo *entry;    //to store a result from linked list
:
:
:
for (entry = result; entry != NULL; entry = entry->ai_next)
{
:
:
:
}

我的问题是为什么 result 是唯一传递给 freeaddrinfo 而不是 hintsentry 的结构?换句话说,我从未见过有人打电话给freeaddrinfo(hints)

还有一件事,我应该为 addrinfo 形式的结构预分配内存或初始化结构吗?如果是这样,我该怎么做?

  1. 粗略浏览了一下...是因为getaddrinfo是动态分配内存的吗?

是的。更具体地说,它为 result 指针指向的链表分配内存。由于库代表您分配内存,库实现者还为您提供了 API 来释放内存。

  1. 如果是这样的话,我应该在上面的例子中预分配内存/初始化entry吗?为什么不将其传递给 freeaddrinfo

没有。 entry 只是一个用于遍历列表的变量。它与

非常相似
`for (i = 0; i < n; i++)` 

循环你会在其他任何地方找到。 i 只是一个迭代器。

如果您不想,您根本不必使用 entry 变量。你可以用 while 循环遍历链表

while (result != NULL) {
    //Do what you have to do here

    result = result->ai_next;
}

如果仔细观察,您会发现您正在将 result 变量本身移动到列表的末尾。如果您以这种方式进行迭代,您将无法释放内存,因为您丢失了由 getaddrinfo() 返回给您的起始地址。要解决这个问题,您可以将起始地址保存在一个临时变量中,然后使用 while 循环。只需在 while 循环之前添加这一行。

struct addrinfo *entry = result; //save the starting address
while (...) {

}

您现在可以在 entry 指针上调用 free,而不是 result。效果是一样的

freeaddrinfo(entry);