Tôi gặp một lỗi thời gian chạy "đôi miễn phí hoặc tham nhũng" trong chương trình C++ của tôi gọi một thư viện ANN đáng tin cậy và sử dụng OpenMP để parallize một vòng lặp for.double miễn phí hoặc tham nhũng
*** glibc detected *** /home/tim/test/debug/test: double free or corruption (!prev): 0x0000000002527260 ***
Có nghĩa là bộ nhớ tại địa chỉ 0x0000000002527260 được giải phóng nhiều lần?
Lỗi xảy ra tại "_search_struct-> annkSearch (queryPt, k_max, nnIdx, dists, _eps);" bên trong hàm classify_various_k(), lần lượt bên trong hàm OpenMP for-loop bên trong hàm tune_complexity().
Lưu ý rằng lỗi xảy ra khi có nhiều hơn một luồng cho OpenMP, và không xảy ra trong trường hợp chuỗi đơn lẻ. Không chắc chắn lý do tại sao.
Sau đây là mã của tôi. Nếu nó không đủ để chẩn đoán, hãy cho tôi biết. Cảm ơn bạn đã giúp đỡ!
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;
}
}
......
}
UPDATE:
Cảm ơn! Bây giờ tôi đang cố gắng để khắc phục xung đột về văn bản cho vấn đề bộ nhớ cùng trong classify_various_k() bằng cách sử dụng "#pragma OMP quan trọng":
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;
}
Tuy nhiên, có một lỗi lỗi phân khúc mới tại "Kết quả + = _ nhãn [nnIdx [i]]; ". Một số ý tưởng? Cảm ơn!
Dùng thử mà không có openmp - có hoạt động chính xác không? –
Tôi khuyên bạn nên biên dịch bằng -g và chạy qua valgrind nếu bạn đang sử dụng OSX hoặc Linux. Điều đó sẽ xác định lỗi cho bạn. –
@Kornel: Nó hoạt động chính xác cho trường hợp đơn luồng. – Tim