我正在使用Win7 / VS2008(9)SDK 6 / 7.1
我遇到了一个我正在使用的代码问题 代码的迷你版本如下
class CONNECTION
{
int/std::string/bool vars; // just to make it simple
CONNECTION ( int defaultvar );
CONNECTION ( const CONNECTION& copycon )
~CONNECTION ( );
DWORD static WINAPI staticstart( void *param ) //HACK to use createthread on classes
{ return ((CONNECTION *)param)->main); } // yea it works fine
DWORD main();
};
此类没有带有副本和析构函数的默认构造函数 所有变量都被复制得很好并且析构函数不会留下任何memleaks,构造函数很简单,因为将参数赋给var。所有变量和代码都被省略以使其变得简单并且因为它们不是概率。
class main
{
std::vector<CONNECTION> con;
int addcon( int defaultvarofcon )
{
CONNECTION temp( defaultvar );
con.push_back( temp );
return con.size() - 1;
}
}
到目前为止一切顺利
当我运行一个只有一个包含此代码的控制台测试程序时
main mymainclass;
mymainclass.addcon( 0 );
程序运行良好关闭没有错误
但是当我添加额外的代码,如
main mymainclass;
mymainclass.addcon( 0 );
mymainclass.addcon( 1 );
mymainclass.addcon( 2 );
程序因访问冲突而崩溃 在检查了我的代码两次后,我逐步调试了所有线程,我发现主线程只能读取主线程和工作线程中所有向量类/元素的正确值,如果我在向量中使用一个元素
然而,如果我使用多个像第二个代码一样的话,那么他们自己线程上所有元素的所有数据都是不可访问的(坏指针)。但在主线程上,他们仍然纠正并显示正确的值
任何人都可以帮我弄清楚这段代码有什么问题吗?
答案 0 :(得分:2)
std::vector
不是设计为线程安全的。因此,您必须使用某种互斥锁来确保一次只能访问一个线程。
否则,如果任何线程调整了向量的大小,向量可能必须分配新的存储,复制元素,然后释放旧存储...并且显然释放旧存储,而其他一些线程正在使用它是一件非常糟糕的事情
您需要自己分配CONNECTION
个对象。让std::vector
管理它们意味着当向量调整大小时它们会在内存中移动,而其他线程持有的指针会悬空。调整向量大小会使指向其任何内容的所有指针无效。
答案 1 :(得分:1)
如果您需要自定义析构函数和复制构造函数,则probably也需要自定义赋值运算符。
如果没有它,你很快会得到你的类的几个实例引用相同的内部指针/ ...,很容易导致内存损坏和访问冲突。