src.cpp
#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int main(){
struct addrinfo hints, *servinfo;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(NULL, "1560", &hints, &servinfo);
freeaddrinfo(&hints);
}
I used gdb to find out where the error occurs and it occurs at the memset but when I comment out the call to freeaddrinfo(), it gives no error and works!
I am running Ubuntu 20.04.2 kernel 5.8.0-55-generic
edit: as you pointed out that I should give freeaddrinfo a list provided by getaddrinfo, when I pass servinfo to freeaddrinfo, it gives the following error
double free or corruption (out)
[1] 4123 abort (core dumped) ./a.out
edit 2: thanks, when editing the question I forgot to replace the &hints with servinfo, and thought that I had already replaced it, sorry for the inconvinience, I deserve every bit of downvote for my stupidity.
freeaddrinfo(&hints);
This is expected behaviour (in the way that it the behaviour is undefined; not in the way that you could rely on this behaviour). You may only pass structure created by getaddrinfo
into freeaddrinfo
. You didn't create &hints
with getaddrinfo
. Don't pass hints
into freeaddrinfo
.
A fixed example:
addrinfo hints {
.ai_flags = AI_PASSIVE,
.ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM,
};
addrinfo* result;
int err = getaddrinfo(nullptr, "12345", &hints, &result);
if (err) {
std::cout << "getaddrinfo: " << gai_strerror(err);
std::exit(EXIT_FAILURE);
} else {
// use it here
freeaddrinfo(result); // pay particular attention to this
}
I replaced it with freeaddrinfo(servinfo);
Your new example still has freeaddrinfo(&hints)
but also freeaddrinfo(servinfo)
. If you replace the former with the latter, then you're calling freeaddrinfo(servinfo)
twice. You may not use the invalidated servinfo
after you've freed it, including passing it into freeaddrinfo
a second time. Similar rules apply as would apply to std::free
.