Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    [C++ 2010 Win32Console] Unhandled Exception su statement "return"

    Ciao a tutti,
    si tratta di una applicazione C++ di Computer Vision che sto sviluppando con Visual Studio 2010, utilizzando la libreria OpenCv.
    Il mio problema è che ottengo una Unhandled Exception di tipo Access Violation in corrispondenza dello statement di return di una funzione, eppure si tratta di una semplice "return 1" e il tipo di ritorno della function è int.
    Se eseguo un debug, la freccetta che segnala l'istruzione causa dell'errore si ferma proprio in corrispondenza del return. Anche inserendo printf prima (nella function) e dopo (nel chiamate) il return, quella prima viene eseguita e quella dopo no.
    Sapete come posso fare a capire quale sia la causa dell'eccezione?
    Grazie in anticipo.

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Di sicuro hai un puntatore che per qualche motivo viene cancellato due volte.
    Ma senza vedere il codice non è possibile dire di più.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  3. #3
    Guarda se per cancellazione del puntatori intendi l'esecuzione di "delete" io non ne eseguo nemmeno una.
    Cmq nel caso volessi dare un'occhiata al codice lo posto. Questa che riporto è la function che genera l'eccezione, qualsiasi delle due return venga eseguita:

    codice:
    int extractAndMatchFeaturesSURF_F2R(IplImage *pRefImage,IplImage *pTrgImage, CvPoint2D32f *pRefCorners, CvPoint2D32f* pTrgCorners, int *pCorners, cv::flann::Index flann_index, CvSeq* refImgKeypoints, CvSeq* refImgDescriptors)
    {
        CvSeq* trgImgKeypoints = 0, *trgImgDescriptors = 0;
        CvSURFParams params = cvSURFParams(HESSIAN_THRESHOLD, 0);
        CvMemStorage* storage = cvCreateMemStorage(0);
        vector<int> ptpairs;
        CvSize sImageSize=cvGetSize(pRefImage);
    
        IplImage* pGrayTrgImage=cvCreateImage(sImageSize,IPL_DEPTH_8U,1);
        cvCvtColor(pTrgImage,pGrayTrgImage,CV_RGB2GRAY);
        cvExtractSURF( pGrayTrgImage, 0, &trgImgKeypoints, &trgImgDescriptors, storage, params);
    	
        flannFindPairs_F2R( refImgKeypoints, refImgDescriptors, trgImgKeypoints, trgImgDescriptors, ptpairs, flann_index);
    
        *pCorners = (int)(ptpairs.size()/2);
        if( *pCorners < 4 )
            return 0;
    
        int i;
        for( i = 0; i < *pCorners; i++ )
        {
            pRefCorners[i] = ((CvSURFPoint*)cvGetSeqElem(refImgKeypoints,ptpairs[i*2]))->pt;
            pTrgCorners[i] = ((CvSURFPoint*)cvGetSeqElem(trgImgKeypoints,ptpairs[i*2+1]))->pt;
        }
        return 1;
    }
    Tutte le funzioni invocate fanno parte o delle librerie native C++ o delle librerie OpenCv tranne la flannFindPairs_F2R di cui riporto il codice:

    codice:
    void flannFindPairs_F2R( const CvSeq*, const CvSeq* imageDescriptors, const CvSeq*, const CvSeq* objectDescriptors, vector<int>& ptpairs,  cv::flann::Index flann_index)
    {
        int length = (int)(objectDescriptors->elem_size/sizeof(float));
        cv::Mat m_object(objectDescriptors->total, length, CV_32F);
    
        // copy descriptors
        CvSeqReader obj_reader;
        float* obj_ptr = m_object.ptr<float>(0);
        cvStartReadSeq( objectDescriptors, &obj_reader );
        for(int i = 0; i < objectDescriptors->total; i++ )
        {
            const float* descriptor = (const float*)obj_reader.ptr;
            CV_NEXT_SEQ_ELEM( obj_reader.seq->elem_size, obj_reader );
            memcpy(obj_ptr, descriptor, length*sizeof(float));
            obj_ptr += length;
        }
    	
        // find nearest neighbors using FLANN
        cv::Mat m_indices(objectDescriptors->total, 2, CV_32S);
        cv::Mat m_dists(objectDescriptors->total, 2, CV_32F);
        flann_index.knnSearch(m_object, m_indices, m_dists, 2, cv::flann::SearchParams(64) ); // maximum number of leafs checked
    
        int* indices_ptr = m_indices.ptr<int>(0);
        float* dists_ptr = m_dists.ptr<float>(0);
        for (int i=0;i<m_indices.rows;++i) {
        	if (dists_ptr[2*i]<5.6*dists_ptr[2*i+1]) {
        		ptpairs.push_back(i);
        		ptpairs.push_back(indices_ptr[2*i]);
        	}
        }
    }

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da andrea2453
    Guarda se per cancellazione del puntatori intendi l'esecuzione di "delete" io non ne eseguo nemmeno una.
    Ciò non esclude che qualcos'altro lo faccia al posto tuo, specie se il framework utilizza smart pointer come mi pare di capire.

    In ogni caso quel comportamento è tipico di una doppia cancellazione, un accesso a una zona di memoria non allocata o a un accesso a una zona di memoria oltre i limiti consentiti.
    In particolare mi viene il sospetto che questa linea di codice:
    codice:
    float* obj_ptr = m_object.ptr<float>(0);
    prepari uno smart pointer per un solo float, dove invece ti serve un array.
    In questo caso la memcpy corrompe la memoria e l'effetto è di avere quella violazione.
    Il fatto che si verifichi all'uscita dell'altra funzione è puramente casuale.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  5. #5
    In particolare mi viene il sospetto che questa linea di codice:
    codice:
    float* obj_ptr = m_object.ptr<float>(0);
    prepari uno smart pointer per un solo float, dove invece ti serve un array.
    In questo caso la memcpy corrompe la memoria e l'effetto è di avere quella violazione.
    Però in un'altra versione delle 2 funzioni compare quella istruzione e funziona tutto correttamente:
    codice:
    int extractAndMatchFeaturesSURF_F2F(IplImage *pRefImage,IplImage *pTrgImage, CvPoint2D32f *pRefCorners, CvPoint2D32f* pTrgCorners, int *pCorners)
    {
        CvSeq* refImgKeypoints = 0, *refImgDescriptors = 0;
        CvSeq* trgImgKeypoints = 0, *trgImgDescriptors = 0;
        CvSURFParams params = cvSURFParams(HESSIAN_THRESHOLD, 0);
        CvMemStorage* storage = cvCreateMemStorage(0);
        vector<int> ptpairs;
    
        CvSize sImageSize=cvGetSize(pRefImage);
        IplImage* pGrayRefImage=cvCreateImage(sImageSize,IPL_DEPTH_8U,1);
        cvCvtColor(pRefImage,pGrayRefImage,CV_RGB2GRAY);
        cvExtractSURF( pGrayRefImage, 0, &refImgKeypoints, &refImgDescriptors, storage, params );
    
        IplImage* pGrayTrgImage=cvCreateImage(sImageSize,IPL_DEPTH_8U,1);
        cvCvtColor(pTrgImage,pGrayTrgImage,CV_RGB2GRAY);
        cvExtractSURF( pGrayTrgImage, 0, &trgImgKeypoints, &trgImgDescriptors, storage, params);
    
        flannFindPairs_F2F( refImgKeypoints, refImgDescriptors, trgImgKeypoints, trgImgDescriptors, ptpairs );
    
        *pCorners = (int)(ptpairs.size()/2);
        if( *pCorners < 4 )
            return 0;
    
        int i;
        for( i = 0; i < *pCorners; i++ )
        {
            pRefCorners[i] = ((CvSURFPoint*)cvGetSeqElem(refImgKeypoints,ptpairs[i*2]))->pt;
            pTrgCorners[i] = ((CvSURFPoint*)cvGetSeqElem(trgImgKeypoints,ptpairs[i*2+1]))->pt;
        }
    	 
    }
    codice:
    void flannFindPairs_F2F( const CvSeq*, const CvSeq* objectDescriptors, const CvSeq*, const CvSeq* imageDescriptors, vector<int>& ptpairs )
    {
        int length = (int)(objectDescriptors->elem_size/sizeof(float));
        cv::Mat m_object(objectDescriptors->total, length, CV_32F);
        cv::Mat m_image(imageDescriptors->total, length, CV_32F);
    
        // copy descriptors
        CvSeqReader obj_reader;
        float* obj_ptr = m_object.ptr<float>(0);
        cvStartReadSeq( objectDescriptors, &obj_reader );
        for(int i = 0; i < objectDescriptors->total; i++ )
        {
            const float* descriptor = (const float*)obj_reader.ptr;
            CV_NEXT_SEQ_ELEM( obj_reader.seq->elem_size, obj_reader );
            memcpy(obj_ptr, descriptor, length*sizeof(float));
            obj_ptr += length;
        }
        CvSeqReader img_reader;
        float* img_ptr = m_image.ptr<float>(0);
        cvStartReadSeq( imageDescriptors, &img_reader );
        for(int i = 0; i < imageDescriptors->total; i++ )
        {
            const float* descriptor = (const float*)img_reader.ptr;
            CV_NEXT_SEQ_ELEM( img_reader.seq->elem_size, img_reader );
            memcpy(img_ptr, descriptor, length*sizeof(float));
            img_ptr += length;
        }
    
        // find nearest neighbors using FLANN
        cv::Mat m_indices(objectDescriptors->total, 2, CV_32S);
        cv::Mat m_dists(objectDescriptors->total, 2, CV_32F);
        cv::flann::Index flann_index(m_image, cv::flann::KDTreeIndexParams(4));  // using 4 randomized kdtrees
        flann_index.knnSearch(m_object, m_indices, m_dists, 2, cv::flann::SearchParams(64) ); // maximum number of leafs checked
    
        int* indices_ptr = m_indices.ptr<int>(0);
        float* dists_ptr = m_dists.ptr<float>(0);
        for (int i=0;i<m_indices.rows;++i) {
        	if (dists_ptr[2*i]<0.6*dists_ptr[2*i+1]) {
        		ptpairs.push_back(i);
        		ptpairs.push_back(indices_ptr[2*i]);
        	}
        }
    }

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Non si sa mai cosa succede quando si corrompe la memoria. Il fatto che l'altra funzione non dia problemi può dipendere dall'ordine di invocazione.
    Comunque se quel ptr:
    codice:
    float* obj_ptr = m_object.ptr<float>(0);
    è questo ptr:
    http://opencv.willowgarage.com/docum...tures.html#ptr
    direi che il problema si spiega subito.
    Prima crei un ptr == NULL, poi cerchi di accederci forzando un cast e passandolo alla memcpy.
    Tra l'altro quel tipo di puntatore non ha l'aria di poter essere adattato facilmente agli array.
    Se allochi la memoria con un new[] per avere un array, specializzare la delete_obj per una array di float, ti impedirebbe di ridefinirlo per cancellare un singolo float.

    Se invece quel ptr fa riferimento a un oggetto Mat, dovresti iniziare a mettere qualche assert in giro per verificare che i puntatori siano validi. Tipo
    codice:
    float* obj_ptr = m_object.ptr<float>(0);
    assert(obj_ptr != nullptr);
    Etc.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.