无法将套接字对象移动到std :: vector中

时间:2012-09-07 12:38:00

标签: c++ multithreading sockets c++11 stdvector

我有以下代码:

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时,我松开了袜子对象。

我有一种感觉,它与正确指定副本和/或移动构造函数有关,但我已经定义了两个(和使用的断点来查看将被调用的时间),但它们似乎根本没有被调用。

2 个答案:

答案 0 :(得分:4)

当您说push_back时,对向量元素的引用无效。您不能以您拥有的方式使用代码。您必须首先填充整个矢量,然后再不要再触摸它。或者,使用一个容器,其元素引用不会被容器突变无效(listmultisetunordered_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[]处的元素。