У меня есть следующий код:
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
Я теряю предмет носка.
У меня есть ощущение, что это связано с правильным заданием конструктора копирования и / или перемещения, но я определил оба (и использовал точки останова, чтобы увидеть, когда будет вызываться), но они, похоже, вообще не вызываются.
Ссылки на векторные элементы становятся недействительными, когда вы говорите push_back
, Вы не можете использовать код, как у вас. Вы должны сначала заполнить весь вектор, а затем никогда больше не трогать его. В качестве альтернативы используйте контейнер, ссылки на элементы которого не являются недействительными из-за мутаций контейнера (list
или же multiset
или же unordered_multiset
для общего назначения, deque
для вставки / удаления на концах).
Или просто передать копия указателя на ветку ?!
std::vector<HAS::TCPSocket*> sockets(MAXCONN);
...
sockets.push_back(sock);
std::thread handler(handleTCPClient, std::ref(sockets[socketCount++]));
Этот код выглядит смешно. Вектор будет содержать 4 нулевых указателя, за которыми следуют фактические указатели, которые добавляются в конце с push_back()
звонки. Затем потоки получат ссылки на первые нулевые указатели, а не на нужные указатели.
Вы можете сделать одну из двух вещей: я бы предложил использовать конструктор по умолчанию для вектора, а затем вызвать reserve()
чтобы гарантировать, что не будет перераспределений, которые делают недействительными итераторы с push_backs
, Это решило бы проблему. Кроме того, вы можете создать вектор с элементами, но затем не вызывать push_back()
но лучше использовать operator[]
изменить элемент в позиции socketCount
,