我在使用freeaddrinfo(.)的一些网络代码上遇到了麻烦。使用2012 x64。代码如下所示:
struct addrinfo hints = {0};
hints.ai_family = AF_INET; // only use IPv4
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_ADDRCONFIG;
struct addrinfo *res = nullptr;
int status = getaddrinfo(_rIP.c_str(), std::to_string(_port).c_str(), &hints, &res);
if (status == 0)
{
addDestAddress(res->ai_addr);
}
freeaddrinfo(res);
getaddrinfo/freeaddrinfo在代码的几个地方使用,我在发布模式中得到一致的崩溃。addDestAddress的代码如下:
void addDestAddress(const sockaddr *_pAddr)
{
m_vecDestAddrs.push_back(*(sockaddr_storage*)_pAddr);
}
这是freeaddrinfo的正确用法吗?如果我删除freeaddrinfo调用,除了可能的内存泄漏之外,一切都工作得很好。
编辑--这段代码现在工作得很完美。根据雷米·莱博的答案编辑。
struct addrinfo hints = {0};
hints.ai_family = AF_INET; // only use IPv4
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_ADDRCONFIG;
struct addrinfo *res = nullptr;
int status = getaddrinfo(_rIP.c_str(), std::to_string(_port).c_str(), &hints, &res);
if (status == 0)
{
if (res->ai_family == AF_INET)
{
addDestAddress((sockaddr_in*)res->ai_addr);
}
freeaddrinfo(res);
}
然后,addDestAddress的代码如下:
void addDestAddress(const sockaddr_in *_pAddr)
{
sockaddr_storage ssaddr = {0};
memcpy(&ssaddr, _pAddr, sizeof(sockaddr_in));
m_vecDestAddrs.push_back(ssaddr);
}
这只用于IPv4 UDP工作,不需要IPv6支持。
发布于 2014-06-30 20:15:46
你犯了两个错误:
freeaddrinfo()
,即使getaddrinfo()
失败了。别干那事。res->ai_addr
是一个sockaddr_storage*
,但它不是。相反,它是一个sockaddr_in*
,因为hints.ai_family
是AF_INET
(如果您使用了AF_INET6
,它将是sockaddr_in6
,而AF_UNSPEC
可能是其中之一)。sockaddr_in
比sockaddr_storage
小,所以在将ai_addr
数据复制到向量时访问内存是错误的。试一试:
struct addrinfo hints = {0};
hints.ai_family = AF_INET; // only use IPv4
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_ADDRCONFIG;
struct addrinfo *res = nullptr;
int status = getaddrinfo(_rIP.c_str(), std::to_string(_port).c_str(), &hints, &res);
if (status == 0)
{
addDestAddress((sockaddr_in*) res->ai_addr);
freeaddrinfo(res);
}
void addDestAddress(const sockaddr_in *_pAddr)
{
sockaddr_storage ssaddr = {0};
memcpy(&ssaddr, _pAddr, sizeof(sockaddr_in));
m_vecDestAddrs.push_back(ssaddr);
}
或者这个:
struct addrinfo hints = {0};
hints.ai_family = AF_INET; // only use IPv4
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_ADDRCONFIG;
struct addrinfo *res = nullptr;
int status = getaddrinfo(_rIP.c_str(), std::to_string(_port).c_str(), &hints, &res);
if (status == 0)
{
addDestAddress(res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
}
void addDestAddress(const sockaddr *_pAddr, int addrlen)
{
switch (addrlen)
{
case sizeof(sockaddr_in):
case sizeof(sockaddr_in6):
{
sockaddr_storage ssaddr = {0};
memcpy(&ssaddr, _pAddr, addrlen);
m_vecDestAddrs.push_back(ssaddr);
break;
}
}
}
发布于 2014-06-30 14:00:41
来自文档,我的重点是:
由成功的调用分配给该函数的内存必须与随后对freeaddrinfo的调用一起释放。
你没有注意到这条指令。你无条件地打电话给freeaddrinfo
。只有当对freeaddrinfo
的调用成功时,才必须调用getaddrinfo
。
https://stackoverflow.com/questions/24491776
复制相似问题