【问题标题】:Memory management with `addrinfo` structures使用 `addrinfo` 结构的内存管理
【发布时间】:2018-07-15 07:27:47
【问题描述】:

我刚刚开始在 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 形式的结构预分配内存还是初始化结构?如果是这样,我该怎么做?

【问题讨论】:

  • 只是略过...是因为getaddrinfo动态分配内存?
  • 如果是这种情况,我是否应该在上面的示例中预先分配内存/初始化entry?为什么不传递给freeaddrinfo
  • 在 cmets 部分很难回答您的问题。我要回复一个答案
  • 这个问题和UDP完全没有关系,去掉标签。

标签: c sockets getaddrinfo


【解决方案1】:
  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 指针上免费调用,而不是result。效果是一样的。

freeaddrinfo(entry);

【讨论】:

  • 有趣...我认为迭代器只是整数。听起来像一罐蠕虫打开:)
  • 阅读指针算法。起初理解它有点棘手。但是如果你想使用C语言就需要它
猜你喜欢
  • 2012-04-22
  • 2021-11-01
  • 1970-01-01
  • 2012-03-24
  • 1970-01-01
  • 1970-01-01
  • 2019-06-01
  • 1970-01-01
  • 2014-03-23
相关资源
最近更新 更多