使用 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
而不是 hints
或 entry
的结构?换句话说,我从未见过有人打电话给freeaddrinfo(hints)
。
还有一件事,我应该为 addrinfo
形式的结构预分配内存或初始化结构吗?如果是这样,我该怎么做?
- 粗略浏览了一下...是因为getaddrinfo是动态分配内存的吗?
是的。更具体地说,它为 result
指针指向的链表分配内存。由于库代表您分配内存,库实现者还为您提供了 API 来释放内存。
- 如果是这样的话,我应该在上面的例子中预分配内存/初始化
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);
我刚开始使用 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
而不是 hints
或 entry
的结构?换句话说,我从未见过有人打电话给freeaddrinfo(hints)
。
还有一件事,我应该为 addrinfo
形式的结构预分配内存或初始化结构吗?如果是这样,我该怎么做?
- 粗略浏览了一下...是因为getaddrinfo是动态分配内存的吗?
是的。更具体地说,它为 result
指针指向的链表分配内存。由于库代表您分配内存,库实现者还为您提供了 API 来释放内存。
- 如果是这样的话,我应该在上面的例子中预分配内存/初始化
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);