2013-06-30 2 views
0

Я получаю следующее сообщение об ошибке при запуске приложения, которое считывает некоторые данные из файлов, извлекает особенности изображения и предсказывает результат, используя набор заранее подготовленных классификаторов:OpenCV бесплатно(): недопустимый указатель:

> *** glibc detected *** ./SVMread: free(): invalid pointer: 0xbfeb2670 *** 
> ======= Backtrace: ========= /lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb5fe8ee2] 
> /usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x1f)[0xb61e451f] 
> ./SVMread(_ZN2cv17FlannBasedMatcherD0Ev+0x1c)[0x804b214] 
> ./SVMread[0x804ca96] ./SVMread[0x804c0e1] 
> ./SVMread(_ZN2cv3PtrINS_17DescriptorMatcherEED1Ev+0x11)[0x804b6e9] 
> ./SVMread[0x804a8cc] 
> /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb5f8c4d3] 
> ./SVMread[0x8049ef1] 
> ======= Memory map: ======== 08048000-08050000 r-xp 00000000 00:14 101213  /home/srt/OpenCV-2.4.2/samples/cpp/SVMread 
> 08050000-08051000 r--p 00007000 00:14 101213  
> /home/srt/OpenCV-2.4.2/samples/cpp/SVMread 08051000-08052000 rw-p 
> 00008000 00:14 101213  /home/srt/OpenCV-2.4.2/samples/cpp/SVMread 
> ... 

Я думаю, что конфликтная часть находится в одном из следующих разделов кода, но я действительно не могу найти решение в Интернете или в документации OpenCV.

 SurfDescriptorExtractor extractor1; 
    Ptr<DescriptorExtractor> extractor = &extractor1; 
    FlannBasedMatcher matcher1; 
    Ptr<DescriptorMatcher> matcher = &matcher1; 

    BOWImgDescriptorExtractor bowide(extractor,matcher); 

или:

CvFileStorage* storage = cvOpenFileStorage("svm1.yml", 0, CV_STORAGE_READ); 

const char * c; 
string clase; 
CvFileNode* cFN; 

for (unsigned int i = 0; i<Vclases.size(); i++) {    
    clase = Vclases[i]; 
    c = (clase).c_str();      
    cFN = cvGetFileNodeByName(storage , 0, c);   
    cout << "reading " << clase << endl; 
    classes_classifiers[clase].read(storage, cFN);   

} 

Edit: Выход Valgrind подтверждает, что существует проблема в:

CvFileStorage* storage = cvOpenFileStorage("svm1.yml", 0, CV_STORAGE_READ); 

Valgrind:

> Conditional jump or move depends on uninitialised value(s) 
> ==23398== at 0x56585C0: ____strtod_l_internal (strtod_l.c:1659) 
> ==23398== by 0x5653FAE: strtod (strtod.c:70) 
> ==23398== by 0x41425B1: icv_strtod(CvFileStorage*, char*, char**) (in /usr/local/lib/libopencv_core.so.2.4.2) 
> ==23398== by 0x415875F: icvYMLParseValue(CvFileStorage*, char*, CvFileNode*, int, int) (in /usr/local/lib/libopencv_core.so.2.4.2) 
> ==23398== by 0x804A377: main (SVMread.cpp:64) 
> ==23398== Uninitialised value was created by a stack allocation 
> ==23398== at 0x56575E4: ____strtod_l_internal (strtod_l.c:424) 

Я новичок с указателями и распределением памяти, поэтому любой h elp будет оценен. Заранее спасибо.

ответ

0

Я нашел решение: проблема заключалась в том, что cv: Ptr работает с динамически выделенными объектами, поэтому при попытке освободить указатели, инициализированные ссылкой, происходит ошибка. Таким образом, правильное объявление указателей:

Ptr<DescriptorMatcher > matcher = new FlannBasedMatcher; 
Ptr<DescriptorExtractor > extractor(new SurfDescriptorExtractor()); 

И ошибка сегментации исчезла.

(Примечание: я нашел решение, которое было получено здесь: OpenCV/C++ - How to free pointers