我有以下代码:
try
{
HAS::TCPServerSocket servSock(echoServPort); // Socket descriptor for server
std::vector<HAS::TCPSocket*> sockets(MAXCONN);
for (;;)
{
try
{
if (socketCount < MAXCONN)
{
HAS::TCPSocket* sock(servSock.accept());
sockets.push_back(sock);
std::thread handler(handleTCPClient, std::ref(sockets[socketCount++]));
handler.detach();
}
}
catch (...)
{
cerr << "Unable to create thread" << endl;
exit(1);
}
}
}
我希望跟踪有限数量的连接(MAXCONN=4)
,并希望使用std::vector
跟踪已打开的套接字。不知何故,当我使用上面的代码时,sock
变量被正确设置为servSock.accept()
接受的当前套接字。但是,当我尝试将sock
变量推送到std::vector
时,我松开了袜子对象。
我有一种感觉,它与正确指定副本和/或移动构造函数有关,但我已经定义了两个(和使用的断点来查看将被调用的时间),但它们似乎根本没有被调用。
答案 0 :(得分:4)
当您说push_back
时,对向量元素的引用无效。您不能以您拥有的方式使用代码。您必须首先填充整个矢量,然后再不要再触摸它。或者,使用一个容器,其元素引用不会被容器突变无效(list
或multiset
或unordered_multiset
用于通用目的,deque
用于插入/删除末尾)
或者只是将指针的副本传递给线程?!
答案 1 :(得分:2)
std::vector<HAS::TCPSocket*> sockets(MAXCONN);
...
sockets.push_back(sock);
std::thread handler(handleTCPClient, std::ref(sockets[socketCount++]));
该代码看起来很有趣。向量将保存4个空指针,然后是最后添加push_back()
个调用的实际指针。然后,线程将获得对第一个空指针的引用,而不是您想要的实际指针。
您可以执行以下两项操作之一:我的建议是使用向量的默认构造函数,然后调用reserve()
以确保不存在使{{1}的迭代器无效的重新分配}。那样可以解决问题。或者,您可以使用元素创建向量,但不要调用push_backs
,而是使用push_back()
修改位置operator[]
处的元素。