2013-02-19 68 views
1

嗯,我知道很多人都有發佈VS的這個問題。調試模式。我搜查了很多,並通過了我的程序堆棧跟蹤並檢查了指針。但是,我不明白爲什麼我在發佈模式下獲得訪問衝突錯誤,而我的程序在調試模式下完美工作!我在深入ITK代碼後看到一個函數會導致訪問衝突。我先介紹我的代碼,然後調用層次結構導致此訪問衝突:在發佈模式下ITK訪問違規錯誤,但在閱讀DICOM文件時無法在調試模式下

這裏是我的類型定義:

//typedef unsigned char PixelType; 
const unsigned int dimention = 3; 

//STD types 
typedef std::vector<std::string> FileNamesContainer; 
typedef std::vector<std::string> SeriesUIDContainer; 

//ITK Types 
typedef itk::DICOMSeriesFileNames NamesGeneratorType; 
typedef itk::Image <signed short, dimention> ImageType; //Defining Image Type 
typedef itk::ImageSeriesReader<ImageType> ReaderType; //Defining the type of the image series reader 

//GDCM Types 
typedef itk::GDCMImageIO DICOMImageIOType; 

這裏是我的功能:

ReaderType::Pointer itkReadDICOM::ReadImages(char *sourceFolderAddress, std::string &seriesUID) 
{ 
    std::cout<<"- Getting file names in: "<<sourceFolderAddress<<std::endl; 
    std::cout<<"- Series ID: "<<seriesUID<<std::endl; 

    //Creating a pointer to an object of the reader type. ReaderType is defined on top as itk ImageSeriesReader 
    ReaderType::Pointer reader = ReaderType::New(); 

    //Setting the IO type by creating a dicomIO object from the GDCMImageIO. This will make sure we read DICOM images. 
    DICOMImageIOType::Pointer dicomIO = DICOMImageIOType::New(); 
    reader->SetImageIO(dicomIO); 

    //Creating a dicom series name generator. It will generate the name of the dicom series based on the input directory. 
    NamesGeneratorType::Pointer namesGenerator = NamesGeneratorType::New(); 
    namesGenerator->SetDirectory(sourceFolderAddress); 

    //Getting names and passing the names to the reader to read them. 
    FileNamesContainer fileNames = namesGenerator->GetFileNames(seriesUID); 
    reader->SetFileNames(fileNames); 

    std::cout<<"- Reading files ... "; 

    //Adding a reading progress observer to the reader so we can see how are we reading. 
    ITKCmdProgressObserver::Pointer progressObserver = ITKCmdProgressObserver::New(); 
    reader->AddObserver(itk::ProgressEvent(), progressObserver); 

    //Actually reading the files here. If any error happens it will be Printed and the program exists. 
    try 
    { 
     reader->UpdateLargestPossibleRegion(); 
     std::cout<<"Successfully read "<< fileNames.size() <<" file(s)."<<std::endl; 
    } 
    catch (itk::ExceptionObject &ex) 
    { 
     std::cout<<"Failed."<<std::endl<<"*********************************************************************"<<std::endl; 
     std::cout<<ex<<std::endl; 
     std::cout<<"*********************************************************************"<<std::endl; 
     return 0; 
    } 
    return reader; 
} 

調用導致錯誤是這樣的:

reader->UpdateLargestPossibleRegion(); 

上述函數調用通過這個調用鏈終於導致錯誤:

1.

this->UpdateOutputInformation(); //void ProcessObject::UpdateLargestPossibleRegion() 

2.

this->GenerateOutputInformation(); //void ProcessObject::Update() 

3.

reader->UpdateOutputInformation(); //template <class TOutputImage> void ImageSeriesReader<TOutputImage>::GenerateOutputInformation(void) 

4.

this->GenerateOutputInformation(); //void ProcessObject::UpdateOutputInformation() 

5.

m_ImageIO->SetFileName(m_FileName.c_str()); 
m_ImageIO->ReadImageInformation(); //template <class TOutputImage, class ConvertPixelTraits> void ImageFileReader<TOutputImage, ConvertPixelTraits> ::GenerateOutputInformation(void) 

在步驟5中,第一行是精細和第二行導致訪問衝突。它甚至不讓我通過它。我正在使用Visual Studio 2010.我很感謝你的回答。

回答

2

感謝保羅的回答討厭的東西。我平行地嘗試了幾件事,直到現在我找到了解決方案!雖然我不能真正使用gflags來運行我的程序,但是因爲我有一種直覺認爲問題並不在代碼中,所以我沒有花太多時間在它上面。

反正這裏是我做過什麼和解決問題:

我從網上下載ITK網站的樣本稱爲resampleDICOM並編譯它,並有完全相同的問題。所以最初我認爲這是一個ITK錯誤。然後,我通過調試(RelWithDebInfo)在釋放模式下重新編譯ITK,以便在釋放模式下進行調試時可以進入ITK代碼。令我驚訝的是,一個與GDCMImageIO :: MetaDataDictionary相關的完全有效的指針突然變成了一個壞指針(),沒有任何影響它的代碼。所以我意識到應該有一個堆腐敗的地方!我也知道無論是造成這種腐敗不能在我的代碼。

所以我讀了這麼多線程混合調試和發佈的.lib和。DLL文件可以使事情真的很討厭。但我確定我正在使用ITK發佈.lib文件和.dll文件,因爲我多次檢查它們!我的意思是馬亞尼時代!我正準備從陽臺跳下來,結束這種不幸,我有這個想法只是爲了確保我的程序不使用ITK的調試編譯。 因此,我改變ITK debug文件夾的名稱到別的東西並在釋放模式和突然跑到我的程序:

ITKCommon.dll is missing! 

儘管我設置的所有文件夾和所有設置在Visual Studio中使用發佈文件夾,我的程序在運行時從調試文件夾使用ITKCommon.dll。因此我將ITKCommon.dll從發佈版本複製到我的發佈文件夾中,並且瞧!我的程序像一個魅力。

0

嘗試使用gflags(可用於WinSDK的調試工具)或appverifier(我認爲它也在winsdk中)。

當使能對你的應用程序gflag(在調試模式下),它會發現所有與內存發生,並儘快提出一個斷點爲壞事發生

相關問題