程序在一段时间后终止 "std::bad_alloc"
Programm terminating "std::bad_alloc" after some time
我全神贯注于此,但找不到错误。任何人都可以帮助我在哪里我做不好的编程。
一个 boost::thread
通过套接字接收 strings
,将它们拆分为 vector<string>
,然后将它们分类到 shared class
中的正确变量中。其他线程从那里读取。我试图通过互斥使它成为线程安全的,如图 here 所示。
感谢任何帮助,即使是小提示:)
程序是这样终止的:
Looping...<enter to exit>
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted (core dumped)
这是对应的文件。和ROS纠缠不清,但那部分不应该是判决书
class shared
{
public:
shared() : count(0) {/*emp. body*/ } //constructor
void setvec(vector<string> &strVec, int type){
boost::upgrade_lock<boost::shared_mutex> lock(mtx);
boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock);
switch(type) {
case 1: typ1acc = strVec; setsensor[0] = true; break;
case 2: typ2mag = strVec; setsensor[1] = true; break;
case 3: typ3 = strVec; setsensor[2] = true; break;
}/**/
}
vector<string> getvec(int type) {
boost::shared_lock<boost::shared_mutex> lock(mtx);
switch(type) {
case 1: tmp = typ1acc; break;
case 2: tmp = typ2mag; break;
case 3: tmp = typ3; break;
}
return tmp;
}
private:
boost::shared_mutex mtx;
vector<string> tmp;
vector<string> typ1acc;
vector<string> typ2mag;
vector<string> typ3;
};
shared c; //class object
Class 被多个 boost::threads:
调用
//socket function which sorts vectors into shared class
//this happens from one boost::thread
int type; //key sort by sensor type
vector<string> strVec;
c.setvec(strVec,type);
//multiple boost::threads call this to read the vectors
//this happens from multiple boost::thread
strVec = c.getvec(type);
Bo Persson 为我指出了正确的方向。我把 vector<string> tmp
放到它使用的函数中,它运行稳定。
vector<string> getvec(int type) {
boost::shared_lock<boost::shared_mutex> lock(mtx);
vector<string> tmp; //moved into the function
switch(type) { ...}}
我无法解释为什么,但它运行稳定。如果有人可以对此进行扩展,那就太好了。
我认为在函数外部设置 tmp
的问题是互斥析构函数将(或可以)在从 tmp
到永久变量的复制操作之前 运行 导致一个小的 window,其中 tmp
可以被覆盖并导致潜在的数据竞争。
如果您创建简单的伪造 mutex/string 类 来显示它们何时处于 运行,您就可以看到这一点。最后的代码为我输出以下内容(VC++ 2015):
CSimpleString Raw Constructor (g_tmp)
CSimpleString Raw Constructor (result)
CFakeMutex Constructor
CSimpleString Copy Raw Operator (TestFunction)
CSimpleString Copy Constructor (TestFunction)
CFakeMutex Destructor
CSimpleString Copy Operator (TestFunction)
CSimpleString Destructor (TestFunction)
Result = TestFunction
重要行缩进表明您的互斥量在重要副本发生之前是 destroyed/freed。如果将 tmp
放入函数内部,操作顺序似乎不会改变,但由于 tmp
是局部变量,因此不会发生潜在的数据竞争。
下面是用于测试的非常基本的代码。
#include <string.h>
#include <vector>
class CFakeMutex
{
public:
CFakeMutex()
{
printf("CFakeMutex Constructor\n");
}
~CFakeMutex()
{
printf("CFakeMutex Destructor\n");
}
};
class CSimpleString
{
public:
CSimpleString() {
printf("CSimpleString Empty Constructor\n");
}
CSimpleString(const char* pString) : m_String(pString) {
printf("CSimpleString Raw Constructor (%s)\n", pString);
}
CSimpleString(const CSimpleString& String) : m_String(String.m_String) {
printf("CSimpleString Copy Constructor (%s)\n", String.m_String.c_str());
}
~CSimpleString()
{
printf("CSimpleString Destructor (%s)\n", m_String.c_str());
}
CSimpleString& operator=(const CSimpleString& Src)
{
if (&Src == this) return *this;
printf("CSimpleString Copy Operator (%s)\n", Src.m_String.c_str());
m_String = Src.m_String;
return *this;
}
CSimpleString& operator=(const char* pString)
{
printf("CSimpleString Copy Raw Operator (%s)\n", pString);
m_String = pString;
return *this;
}
std::string m_String;
};
CSimpleString g_tmp("g_tmp");
CSimpleString TestFunction()
{
CFakeMutex Mutex;
CSimpleString local_tmp("local_tmp");
//local_tmp = "TestFunction";
//return local_tmp;
g_tmp = "TestFunction";
return g_tmp;
}
int main()
{
CSimpleString result("result");
result = TestFunction();
printf("Result = %s\n", result.m_String.c_str());
return 0;
}
我全神贯注于此,但找不到错误。任何人都可以帮助我在哪里我做不好的编程。
一个 boost::thread
通过套接字接收 strings
,将它们拆分为 vector<string>
,然后将它们分类到 shared class
中的正确变量中。其他线程从那里读取。我试图通过互斥使它成为线程安全的,如图 here 所示。
感谢任何帮助,即使是小提示:)
程序是这样终止的:
Looping...<enter to exit>
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted (core dumped)
这是对应的文件。和ROS纠缠不清,但那部分不应该是判决书
class shared
{
public:
shared() : count(0) {/*emp. body*/ } //constructor
void setvec(vector<string> &strVec, int type){
boost::upgrade_lock<boost::shared_mutex> lock(mtx);
boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock);
switch(type) {
case 1: typ1acc = strVec; setsensor[0] = true; break;
case 2: typ2mag = strVec; setsensor[1] = true; break;
case 3: typ3 = strVec; setsensor[2] = true; break;
}/**/
}
vector<string> getvec(int type) {
boost::shared_lock<boost::shared_mutex> lock(mtx);
switch(type) {
case 1: tmp = typ1acc; break;
case 2: tmp = typ2mag; break;
case 3: tmp = typ3; break;
}
return tmp;
}
private:
boost::shared_mutex mtx;
vector<string> tmp;
vector<string> typ1acc;
vector<string> typ2mag;
vector<string> typ3;
};
shared c; //class object
Class 被多个 boost::threads:
//socket function which sorts vectors into shared class
//this happens from one boost::thread
int type; //key sort by sensor type
vector<string> strVec;
c.setvec(strVec,type);
//multiple boost::threads call this to read the vectors
//this happens from multiple boost::thread
strVec = c.getvec(type);
Bo Persson 为我指出了正确的方向。我把 vector<string> tmp
放到它使用的函数中,它运行稳定。
vector<string> getvec(int type) {
boost::shared_lock<boost::shared_mutex> lock(mtx);
vector<string> tmp; //moved into the function
switch(type) { ...}}
我无法解释为什么,但它运行稳定。如果有人可以对此进行扩展,那就太好了。
我认为在函数外部设置 tmp
的问题是互斥析构函数将(或可以)在从 tmp
到永久变量的复制操作之前 运行 导致一个小的 window,其中 tmp
可以被覆盖并导致潜在的数据竞争。
如果您创建简单的伪造 mutex/string 类 来显示它们何时处于 运行,您就可以看到这一点。最后的代码为我输出以下内容(VC++ 2015):
CSimpleString Raw Constructor (g_tmp)
CSimpleString Raw Constructor (result)
CFakeMutex Constructor
CSimpleString Copy Raw Operator (TestFunction)
CSimpleString Copy Constructor (TestFunction)
CFakeMutex Destructor
CSimpleString Copy Operator (TestFunction)
CSimpleString Destructor (TestFunction)
Result = TestFunction
重要行缩进表明您的互斥量在重要副本发生之前是 destroyed/freed。如果将 tmp
放入函数内部,操作顺序似乎不会改变,但由于 tmp
是局部变量,因此不会发生潜在的数据竞争。
下面是用于测试的非常基本的代码。
#include <string.h>
#include <vector>
class CFakeMutex
{
public:
CFakeMutex()
{
printf("CFakeMutex Constructor\n");
}
~CFakeMutex()
{
printf("CFakeMutex Destructor\n");
}
};
class CSimpleString
{
public:
CSimpleString() {
printf("CSimpleString Empty Constructor\n");
}
CSimpleString(const char* pString) : m_String(pString) {
printf("CSimpleString Raw Constructor (%s)\n", pString);
}
CSimpleString(const CSimpleString& String) : m_String(String.m_String) {
printf("CSimpleString Copy Constructor (%s)\n", String.m_String.c_str());
}
~CSimpleString()
{
printf("CSimpleString Destructor (%s)\n", m_String.c_str());
}
CSimpleString& operator=(const CSimpleString& Src)
{
if (&Src == this) return *this;
printf("CSimpleString Copy Operator (%s)\n", Src.m_String.c_str());
m_String = Src.m_String;
return *this;
}
CSimpleString& operator=(const char* pString)
{
printf("CSimpleString Copy Raw Operator (%s)\n", pString);
m_String = pString;
return *this;
}
std::string m_String;
};
CSimpleString g_tmp("g_tmp");
CSimpleString TestFunction()
{
CFakeMutex Mutex;
CSimpleString local_tmp("local_tmp");
//local_tmp = "TestFunction";
//return local_tmp;
g_tmp = "TestFunction";
return g_tmp;
}
int main()
{
CSimpleString result("result");
result = TestFunction();
printf("Result = %s\n", result.m_String.c_str());
return 0;
}