C++ std 线程和列表分段错误(核心转储)

Posted

技术标签:

【中文标题】C++ std 线程和列表分段错误(核心转储)【英文标题】:C++ std thread and list Segmentation fault (core dumped) 【发布时间】:2018-03-13 09:59:27 【问题描述】:

我是多线程新手,我将在线程中传递一个列表。

我希望一个线程可以添加一个字符串,另一个将删除一个字符串。

我很困惑如何通过列表。

这是我的代码的一部分,它出现了分段错误(核心转储)

struct BOOK 
    list<string> bookName;
;

class itemE 
    ...

    itemE():
        bookList((BOOK*)malloc(sizeof(BOOK)))
    
        count = 0;
        m_addThread = thread(&itemE::add, this, ref(bookList->bookName));           
        ...
       

    void add(list<string>& bkName)
    
        ...
            m_mutex.lock();
            bkName.push_back(name);
            m_mutex.unlock();
        ...
    

;

我试过修改那个

m_addThread = thread(&itemE::add, this, bookList);

void add(BOOK* bk)

    ...
        bk->bookName.push_back(name);
    ...

但还是一样

【问题讨论】:

1.如果你有一个核心文件,看看它。它们不只是浪费你的磁盘空间,它应该帮助你调试。 2. std::thread 构造函数的第一个参数是可调用的。您的成员函数是常规可调用函数吗?当你从课堂外调用它时,语法是什么样的? 问题不是thread而是malloc函数和bookList-&gt;bookNamebookName调用malloc后没有创建,使用new分配内存和构造对象。 如果你在 C++ 中使用 malloc,而不是像编写自己的分配器那样做一些高级的事情,那么你几乎肯定做错了什么。 谢谢@Useless 提醒我调试方法,我会尝试一下,稍后分享结果 谢谢你@Useless 它真的帮了我很多!在我 new BOOK() 之后我忘了加入我的线程。但是通过阅读核心文件和谷歌我找到了它并且它有效! 【参考方案1】:

itemE::add 是您的线程的主体,在此函数成员中,您在 bkName 列表中调用 push_back,但未构造此对象 - 并且您遇到了分段错误。

malloc 函数只分配内存。调用此行malloc(sizeof(BOOK)) 仅分配了sizeof(BOOK) 字节,但未调用bookName 成员的构造函数。您应该使用 new 分配内存并构造您的 BOOK 对象。

itemE():
    bookList(new BOOK)

  ...

new BOOKlist&lt;string&gt; bookName的默认构造函数会被调用,然后你可以在这个成员上使用例如push_back

【讨论】:

呃,我没注意到。 @OP - 在尝试创建多个线程之前学习正确编写单线程代码。这是在尝试任何复杂的事情之前你应该了解的基本内容。【参考方案2】:

考虑改用 lambda

itemE()
 :bookList(new BOOK)

    count = 0;
    m_addThread = thread([this]()  add(bookList->bookName); );  

  

【讨论】:

以上是关于C++ std 线程和列表分段错误(核心转储)的主要内容,如果未能解决你的问题,请参考以下文章

C++中char指针中的memset的分段错误(核心转储)[重复]

C++ 代码的分段错误(核心转储)

c++:分段错误(核心转储)

C++ 地图分段错误(核心转储)

C++ 的核心转储分段错误

在命名管道中获取分段错误(核心转储)错误