程序在一段时间后终止 "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;
}