线程中删除会产生分段错误

时间:2014-06-09 08:50:29

标签: c++ pthreads mutex

此程序计算一行中单词的出现次数。它按预期运行,但我有两个问题:

  1. delete tmp截至目前已被评论(第57行)。如果它被取消注释并编译,我的可执行文件会给出“分段错误”。奇怪的是,它在gdbvalgrind中运行时不会崩溃。
  2. 第65和66行:理想情况下,这些线程需要连接。但是,即使它们没有加入,我也能获得正确的输出。这是它对共享(易变)变量的行为吗?
  3. #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <pthread.h>
    #include <unistd.h>
    #include <fstream>
    #include <new>
    #define MAX_BUFF 1000
    
    using namespace std;
    volatile int tcount=0;
    pthread_mutex_t myMux;
    
    typedef struct data
    {
        string line;
        string arg;
    }tdata;
    
    void *calcWordCount(void *arg)
    {
        tdata *tmp = (tdata *)arg;
        string line = tmp->line;
        string s = tmp->arg;
        int startpos = 0;
        int finds = 0;
        while ((startpos = line.find(s, startpos)) != std::string::npos)
        {
                ++finds;
                startpos+=1;
                pthread_mutex_lock(&myMux);
                tcount++;
                pthread_mutex_unlock(&myMux);
        }
        //cout<<endl<<line<<s<<" "<<finds<<endl;
    }
    int main(int argc,char *argv[])
    {
      pthread_t thread_ids[10000];
      int cnt=1;
      int thread_cnt=0;
      void *exit_status;
      int targc=argc;
      ifstream infile("testfile");  
      string line;
      while(getline(infile,line))
      {
            while(targc >1)
            {
                  tdata *tmp = new tdata;
              tmp->line = line;
                  tmp->arg = argv[cnt];
                  pthread_create(&thread_ids[thread_cnt],NULL,calcWordCount,tmp);
                  thread_cnt++;
                  cnt++;
                  targc--;
                  //delete tmp;
            }
        cnt=1;
        targc=argc;
    
    }
    infile.close();
    int j;
    /*for(j=0;j<thread_cnt;j++)
        pthread_join(thread_ids[j],&exit_status);*/
    cout<<tcount<<endl;
    return 0;
    } 
    

1 个答案:

答案 0 :(得分:0)

当您在delete上调用tmp而另一个线程正在使用它时,您有未定义的行为。

一个修复方法是创建并传递(按值)std::shared_ptr而不是将裸指针传递到工作线程中。您可以在主循环中使用releasereset方法。一旦工作线程完成,std::shared_ptr将释放内存。