C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了c – 双重免费或腐败大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我在我的C程序中遇到了一个运行时错误“double free or corruption”,它调用一个可靠的库Ann并使用OpenMP来平行for循环.
*** glibc detected *** /home/tim/test/debug/test: double free or corruption (!prev): 0x0000000002527260 ***

这是否意味着地址0x0000000002527260的内存被释放多次?

错误发生在“_search_struct-> AnnkSearch(queryPt,k_max,nnIdx,dists,_eps);”内部函数classify_varIoUs_k(),它在函数tune_complexity()内部的OpenMP for循环中.

请注意,当OpenMP有多个线程时会发生错误,并且在单线程情况下不会发生.不知道为什么.

以下是我的代码.如果它不足以进行诊断,请告诉我.谢谢你的帮助!

void KNNClassifier::Train(int nb_examples,int dim,double **features,int * labels) {                         
      _nPts = nb_examples;  

      _labels = labels;  
      _dataPts = features;  

      setTing_Ann(_dist_type,1);   

    delete _search_struct;  
    if(strcmp(_search_neighbors,"brutal") == 0) {                                                                 
      _search_struct = new AnnbruteForce(_dataPts,_nPts,dim);  
    }else if(strcmp(_search_neighbors,"kdtree") == 0) {  
      _search_struct = new Annkd_tree(_dataPts,dim);  
      }  

  }  


      void KNNClassifier::classify_varIoUs_k(int dim,double *feature,int label,int *ks,double * errors,int nb_ks,int k_maX) {            
        Annpoint      queryPt = 0;                                                                                                                
        AnnidxArray   nnIdx = 0;                                                                                                         
        AnndistArray  dists = 0;                                                                                                         

        queryPt = feature;     
        nnIdx = new Annidx[k_max];                                                               
        dists = new Anndist[k_max];                                                                                

        if(strcmp(_search_neighbors,"brutal") == 0) {                                                                               
          _search_struct->AnnkSearch(queryPt,_eps);    
        }else if(strcmp(_search_neighbors,"kdtree") == 0) {    
          _search_struct->AnnkSearch(queryPt,_eps); // where error occurs    
        }    

        for (int j = 0; j < nb_ks; j++)    
        {    
          scalar_t result = 0.0;    
          for (int i = 0; i < ks[j]; i++) {                                                                                      
              result+=_labels[ nnIdx[i] ];    
          }    
          if (result*label<0) errors[j]++;    
        }    

        delete [] nnIdx;    
        delete [] dists;    

      }    

      void KNNClassifier::tune_complexity(int nb_examples,int *labels,int fold,char *method,int nb_examples_test,double **features_test,int *labels_test) {    
          int nb_try = (_k_max - _k_min) / scalar_t(_k_step);    
          scalar_t *error_validation = new scalar_t [nb_try];    
          int *ks = new int [nb_try];    

          for(int i=0; i < nb_try; i ++){    
            ks[i] = _k_min + _k_step * i;    
          }    

          if (strcmp(method,"ct")==0)                                                                                                                     
          {    

            Train(nb_examples,dim,features,labels );// Train once for all nb of nbs in ks                                                                                                

            for(int i=0; i < nb_try; i ++){    
              if (ks[i] > nb_examples){nb_try=i; break;}    
              error_validation[i] = 0;    
            }    

            int i = 0;    
      #pragma omp parallel shared(nb_examples_test,error_validation,features_test,labels_test,nb_try,ks) private(i)    
            {    
      #pragma omp for schedule(dynamiC) Nowait    
              for (i=0; i < nb_examples_test; i++)         
              {    
                classify_varIoUs_k(dim,features_test[i],labels_test[i],ks,ks[nb_try - 1]); // where error occurs    
              }    
            }    
            for (i=0; i < nb_try; i++)    
            {    
              error_validation[i]/=nb_examples_test;    
            }    
          }

          ......
     }

更新:

谢谢!我现在正试图通过使用“#pragma omp critical”来纠正classify_varIoUs_k()中写入相同内存问题的冲突:

void KNNClassifier::classify_varIoUs_k(int dim,int k_maX) {   
  Annpoint      queryPt = 0;    
  AnnidxArray   nnIdx = 0;      
  AnndistArray  dists = 0;     

  queryPt = feature; //for (int i = 0; i < Vignette::size; i++){ queryPt[i] = vignette->content[i];}         
  nnIdx = new Annidx[k_max];                
  dists = new Anndist[k_max];               

  if(strcmp(_search_neighbors,"brutal") == 0) {// search  
    _search_struct->AnnkSearch(queryPt,_eps);  
  }else if(strcmp(_search_neighbors,"kdtree") == 0) {  
    _search_struct->AnnkSearch(queryPt,_eps);  
  }  

  for (int j = 0; j < nb_ks; j++)  
  {  
    scalar_t result = 0.0;  
    for (int i = 0; i < ks[j]; i++) {          
        result+=_labels[ nnIdx[i] ];  // Program received signal SIGSEGV,Segmentation fault
    }  
    if (result*label<0)  
    {  
    #pragma omp critical  
    {  
      errors[j]++;  
    }  
    }  

  }  

  delete [] nnIdx;  
  delete [] dists;  

}

但是,“result = _labels [nnIdx [i]];”中存在新的段错误错误.有些想法?谢谢!

解决方法

好的,既然你已经声明它在单线程情况下可以正常工作,那么“普通”方法将不起作用.您需要执行以下操作:

>查找并行访问的所有变量
>特别是看看那些经过修改
>不要在共享资源上调用delete
>查看在共享资源上运行的所有库函数检查它们是否不进行分配/释放

这是双重删除的候选人列表:

shared(nb_examples_test,ks)

此外,此代码可能不是线程安全的:

for (int i = 0; i < ks[j]; i++) {
         result+=_labels[ nnIdx[i] ]; 
      }    
      if (result*label<0) errors[j]++;

因为两个或多个进程可能会尝试写入错误数组.

还有一个很好的建议 – 在线程模式下尝试不访问(特别是修改!)任何东西,这不是函数的参数!

大佬总结

以上是大佬教程为你收集整理的c – 双重免费或腐败全部内容,希望文章能够帮你解决c – 双重免费或腐败所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。