类vector类型的成员在线程中push_back报错

eternal_tune 2016-11-24 11:52:18
[code=c++]
// 代码:
int SyncTcpServer::start()
{
if (stopRunning) return 0;

listenThread = ::CreateThread(NULL,
0, listenClient, this, 0, NULL);

return 0;
}

// 线程
DWORD WINAPI SyncTcpServer::listenClient(LPVOID arg)
{
SyncTcpServer *pThis = (SyncTcpServer *)arg;
sockaddr_in addr;
int addrLen = sizeof(sockaddr_in);

SOCKET s;
while (!pThis->stopRunning) {
s = accept(pThis->sock, (sockaddr *)&addr, &addrLen);
if (s == INVALID_SOCKET) {
pThis->onServerClosed();
break;
}
pThis->newClientAccepted(s, addr);
}

return 0;
}
void SyncTcpServer::newClientAccepted(SOCKET s, sockaddr_in addr)
{
if (s == INVALID_SOCKET) {
/* something didn't expected happened */
return ;
}

addSock(s, inet_ntoa(addr.sin_addr));
onNewClientAccepted(inet_ntoa(addr.sin_addr));

HANDLE thrd = ::CreateThread(NULL, 0, handleClient, this, 0, NULL);
handleThreads.push_back(thrd);
}

void SyncTcpServer::addSock(SOCKET s, std::string ipAddr)
{
::WaitForSingleObject(mutex, INFINITE);
ClientDesc *newClient = new ClientDesc(s, ipAddr);
clients.push_back(newClient); //出错地
::ReleaseMutex(mutex);
}

// push_back内部出错地
iterator insert(const_iterator _Where, const _Ty& _Val)
{ // insert _Val at _Where
size_type _Off = size() == 0 ? 0 : _Where - begin();
_Insert_n(_Where, (size_type)1, _Val); //确切出错地
return (begin() + _Off);
}
[/code]

// 类型
struct ClientDesc {
ClientDesc(SOCKET sock, std::string addr)
: s(sock), unHandled(true), ipAddr(addr) {}

SOCKET s;
bool unHandled;
std::string ipAddr;
};

在clients声明之前并没有任何成员变量的声明,排除了clients被之前成员覆盖问题。
在调用addSock之前也没有从clients中添加或者删除任何元素,addSock第一次调用就会出错。

只有在release版本时会报错。
将clients替换为vector<int*>也会报错。
将addSock放入非线程处理函数中调用不会出错。

个人怀疑是不是在类指针在传递进线程处理函数的时候出现了某些变化。
请各位大神指点一下。
...全文
321 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
小灸舞 2016-11-24
  • 打赏
  • 举报
回复
怀疑是传递出错就设成全局的试试,看看会不会出错。
还出错,然后再看看是不是多线程锁的问题。
还出错,再单步调试代码看看代码问题。
错误原因一个个排除。
paschen 版主 2016-11-24
  • 打赏
  • 举报
回复
出错时点中断,通过调用堆栈定位到相关位置,观察分析原因,必要时可单步跟踪程序运行
赵4老师 2016-11-24
  • 打赏
  • 举报
回复
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止
赵4老师 2016-11-24
  • 打赏
  • 举报
回复
多线程需要在必要的地方加锁。

64,662

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧