getaddrinfo addrinfo result in stack or heap

2019-07-03 19:02发布

问题:

I am a bit confused at least. getaddrinfo() call 'updates' a pointer to a addrinfo struct, all is well when I am going to use the addrinfo in the same scope (that function) but what happens if I copy the struct to another one (by assigning it).

Please help me understand the undergoing basics (not seeking advice for alternative approaches).

Correct me if I am wrong: a) getaddrinfo() requires a pointer to struct-pointer to addrinfo. b) getaddrinfo creates a addrinfo struct in the current function scope and updates the pointer required in a)

Now my real question: i would like to store that addrinfo somewhere else. Using an assigning to an other pointer does not do a deep copy, and after the function all the pointers become invalid?

Better give an extremely simplified example:

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; 
}

Directly using &update on getaddrinfo seems to not work because the problem remains: the original struct get destroyed after the function scope ends.

Anyone able to give me more insight here (please explain what gets created where and destroyed where, stack, heap all info is welcome)

回答1:

the original struct get destroyed after the function scope ends

No, the struct's pointer is destroyed. The rest of the data is still in the heap. This would be a memory leak if you don't call freeaddrinfo() when you're finished with the result.

i would like to store that addrinfo somewhere else

Since the data still exists, feel free to copy the pointer; no need for a deep copy. From your example:

void GetAddrInfo(struct addrinfo **update)  /* pointer to pointer */
{
    struct addrinfo *res;
    getaddrinfo(xx,xx,xx,&res);
    *update=res;  /* save the pointer to the struct */
}

You would simply call this function with:

struct addrinfo *mycopy;
GetAddrInfo(&mycopy);


回答2:

getaddrinfo allocates a list of addrinfo structures, and gives you the pointer to the head of the list. You release all allocated memory by passing this pointer to freeaddrinfo when you're done with it.

What you're doing is safe enough, but leaks memory.

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


addrinfo * myai;
GetAddrInfo(&myai);
freeaddrinfo(myai)

This approach will not leak memory - you're simply retrieving a pointer to the addrinfo list head.