Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C getaddrinfo addrinfo导致堆栈或堆_C_Networking_Struct_Stack_Heap - Fatal编程技术网

C getaddrinfo addrinfo导致堆栈或堆

C getaddrinfo addrinfo导致堆栈或堆,c,networking,struct,stack,heap,C,Networking,Struct,Stack,Heap,至少我有点困惑。 getaddrinfo()调用“更新”指向addrinfo结构的指针,当我要在同一作用域(该函数)中使用addrinfo时,一切都很好,但是如果我将该结构复制到另一个结构(通过赋值)会发生什么 请帮助我了解正在进行的基础知识(不要寻求其他方法的建议) 如果我错了,请纠正我: a) getaddrinfo()需要指向addrinfo的结构指针。 b) getaddrinfo在当前函数作用域中创建addrinfo结构,并更新 现在我真正的问题是:我想把addrinfo存储在其他地方

至少我有点困惑。 getaddrinfo()调用“更新”指向addrinfo结构的指针,当我要在同一作用域(该函数)中使用addrinfo时,一切都很好,但是如果我将该结构复制到另一个结构(通过赋值)会发生什么

请帮助我了解正在进行的基础知识(不要寻求其他方法的建议)

如果我错了,请纠正我: a) getaddrinfo()需要指向addrinfo的结构指针。 b) getaddrinfo在当前函数作用域中创建addrinfo结构,并更新

现在我真正的问题是:我想把addrinfo存储在其他地方。使用赋值给另一个指针不会进行深度复制,函数完成后所有指针都会失效

最好给出一个非常简单的例子:

void GetAddrInfo(struct addrinfo *update)
{
    struct addrinfo *res;
    getaddrinfo(xx,xx,xx,&res);

    //is this save? After this 'scope' ends all pointed fields are invalid?
    //this doesn't copy the linked list ai_next.
    *update=*res; 
}
直接在getaddrinfo上使用&update似乎不起作用,因为问题仍然存在:在函数作用域结束后,原始结构将被销毁


任何人都可以在这里给我更多的见解(请解释什么在哪里创建,什么在哪里销毁,堆栈,堆所有信息都是受欢迎的)

getaddrinfo
分配一个
addrinfo
结构的列表,并为您提供指向列表头部的指针。完成后,通过将此指针传递到
freeaddrinfo
,可以释放所有分配的内存

你所做的足够安全,但会泄露内存

void GetAddrInfo(struct addrinfo **update)
{
    getaddrinfo(xx,xx,xx,update);
}


addrinfo * myai;
GetAddrInfo(&myai);
freeaddrinfo(myai)
这种方法不会泄漏内存-您只需检索指向addrinfo列表头的指针

函数作用域结束后,原始结构将被销毁

否,结构的指针已销毁。其余数据仍在堆中。如果在处理完结果后不调用
freeaddrinfo()
,这将是内存泄漏

我想把addrinfo储存在别的地方

由于数据仍然存在,请随意复制指针;不需要深度复制。从你的例子来看:

void GetAddrInfo(struct addrinfo **update)  /* pointer to pointer */
{
    struct addrinfo *res;
    getaddrinfo(xx,xx,xx,&res);
    *update=res;  /* save the pointer to the struct */
}
您只需使用以下命令调用此函数:

struct addrinfo *mycopy;
GetAddrInfo(&mycopy);

我知道freeaddrinfo(),想让讨论保持清晰。那么你说在函数作用域结束后结构不会“失效”吗?所以事实上,在我给freeaddrinfo的头部打电话之前,它是不会被移除的?@Ger Teunis:没错。它是从一些私有分配机制分配的,在您调用之前是完全安全的freeaddrinfo@GerTeunis:尽管如此,您不能将
update
传递给freeaddrinfo-它是
res
字段的副本,它不指向列表的原始标题。我将更新答案。谢谢,getaddrinfo是一个特例,因为它不会在范围退出时清除addrinfo结构?谢谢您的反馈。如果我错了,请纠正我:通常,当我创建结构实例时,它将在堆栈右侧创建,并在当前范围完成后“清除”?那么getaddrinfo在这里是一个特例?有没有办法找到保存数据的函数?@Ger所有局部变量都在堆栈上,对吗。但是您没有创建
addrinfo
struct
getaddrinfo()
正在使用
malloc()
为您创建结构,这就是它位于堆中的原因。您所创建的只是指向结构的指针。当函数结束时,指针会消失,但结构本身仍在堆中;但是,所有其他更新结构指针的c函数是否都以相同的方式工作?@Ger
getaddrinfo()
的独特之处在于它接受指向指针的指针并为用户生成一个链表。在我的脑海里,我想不出还有什么其他功能可以做到这一点。大多数C函数采用一个简单的结构指针(不是指向指针的指针);这些函数通常期望用户预先分配结构,而用户通常只是在堆栈上这样做。如有疑问,请在互联网站上查找一个示例。@Ger:否,您需要检查每个函数的文档