मैं अपने सी ++ प्रोग्राम में एक रनटाइम त्रुटि "डबल फ्री या भ्रष्टाचार" से मिला जो विश्वसनीय पुस्तकालय एएनएन कहता है और लूप के लिए लंबित करने के लिए ओपनएमपी का उपयोग करता है।डबल फ्री या भ्रष्टाचार
*** 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() के अंदर ओपनएमपी फॉर-लूप के अंदर बदले में है।
ध्यान दें कि त्रुटि तब होती है जब ओपनएमपी के लिए एक से अधिक धागे होते हैं, और एकल थ्रेड मामले में नहीं होते हैं। यकीन नहीं है कि क्यों।
मेरा कोड निम्नलिखित है। यदि यह निदान के लिए पर्याप्त नहीं है, तो बस मुझे बताएं। आपकी सहायताके लिए धन्यवाद!
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, _nPts, 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, k_max, nnIdx, dists, _eps);
}else if(strcmp(_search_neighbors, "kdtree") == 0) {
_search_struct->annkSearch(queryPt, k_max, nnIdx, dists, _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 dim, double **features, 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, error_validation, nb_try, ks[nb_try - 1]); // where error occurs
}
}
for (i=0; i < nb_try; i++)
{
error_validation[i]/=nb_examples_test;
}
}
......
}
अद्यतन:
धन्यवाद! मैं अब "#pragma omp महत्वपूर्ण" का उपयोग करके classify_various_k() में एक ही स्मृति समस्या को लिखित रूप से संघर्ष को दूर करने के कोशिश कर रहा हूँ:
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; //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, k_max, nnIdx, dists, _eps);
}else if(strcmp(_search_neighbors, "kdtree") == 0) {
_search_struct->annkSearch(queryPt, k_max, nnIdx, dists, _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;
}
हालांकि, वहाँ परिणाम में "एक नया सेगमेंट गलती त्रुटि + = _ लेबल [nnIdx है [मैं] ];"। कुछ विचार? धन्यवाद!
इसे openmp के बिना आज़माएं - क्या यह सही तरीके से काम करता है? –
यदि आप ओएसएक्स या लिनक्स पर हैं तो मैं -g और valgrind के माध्यम से चलने की अनुशंसा करता हूं। यह आपके लिए त्रुटि को इंगित करना चाहिए। –
@ कॉर्नेल: यह सिंगल-थ्रेड केस के लिए सही तरीके से काम करता है। – Tim