Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getaddrinfo addrinfo result in stack or heap

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)

like image 685
Ger Teunis Avatar asked Nov 17 '25 05:11

Ger Teunis


2 Answers

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);
like image 156
chrisaycock Avatar answered Nov 18 '25 21:11

chrisaycock


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.

like image 44
Erik Avatar answered Nov 18 '25 21:11

Erik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!