2013-08-01 47 views
3

請考慮下面的情形:C++訪問衝突讀取位置0xcdcdcdcd錯誤上調用一個函數

我有一個頭文件和其相應的源文件:

exmp.h(頭文件)

exmp.cpp(源文件)

在頭文件我有一個函數聲明bubSort(...)其定義存在於

exmp.cpp

myClass::bubSort(...) 
{ 

.... 
.... 

} 

其中,myClass->exmp.h

定義的類現在,爲了使用該功能bubSort(...)在另一個文件樣品.cpp,我已經在裏面聲明瞭myClass Sample.h如下圖所示:

/*Sample.h*/ 
class myClass; 

class sampleClass 
{ 

    ..... 
    ..... 
    myClass *ptr; 
}; 

現在使用上述ptr,我試圖訪問bubSort(...)在sample.cpp中,如下圖所示:

//Sample.cpp 
#include "exmp.h" 
sampleClass::func(...) 
{ 
    .... 
    .... 
    ptr->bubSort(...); 
} 

編譯過程中,上面的場景不給任何錯誤,但是同時執行,當控制達到ptr->bubSort(...);,我得到一個異常:

訪問衝突讀取位置0xcdcdcdcd

有人會告訴我該如何避免這種情況?

在此先感謝。

+1

你是如何初始化'ptr'的? – Nbr44

+0

這可能意味着你沒有把'ptr'指向任何東西。或者它可能是別的。很難說,因爲你還沒有發佈太多相關的代碼。 – juanchopanza

+2

VC++通常使用值0xcd來標記未初始化的內存。 –

回答

6

ptr是指向myClass的指針,但是您似乎沒有初始化它。換句話說,ptr沒有指向任何東西。這是未初始化 - 指向超空間。

當您嘗試使用未初始化的指針,

ptr->bubSort(...); 

你得到未定義的行爲。你真的很幸運,應用程序崩潰了,因爲任何事情都可能發生。它本來可以工作。

要直接解決此問題,您需要初始化ptr。方式一:

class sampleClass 
{ 
public: 
    sampleClass() 
    : 
    ptr (new myClass) 
    { 
    } 
}; 

(有關時髦:語法的解釋,查找「初始化列表」)

但這種使用動態分配,這是最好的避免。其中一個原因動態分配,最好避免主要的原因是因爲你必須記住要delete任何你new,否則你會泄漏內存:

class sampleClass 
{ 
public: 
    ~sampleClass() 
    { 
    delete ptr; 
    } 
}; 

問問自己,如果你真的需要一個指針在這裏,或不將做好嗎?

class sampleClass 
{ 
public: 
    myClass mMyClass; 
}; 

sampleClass::func(...) 
{ 
    mMyClass.func(); 
} 
1

你沒有初始化指針,所以你要調用空內存。它是0xcdcdcdcd,而不是一些隨機的東西,因爲可視化調試器。

ptr = new myClass();

這樣做。但在這種情況下,您根本不必使用指針。

+1

不是「調用空的內存」,而是「喚起未定義的行爲」。 –

+0

@John你能否詳細說明你的意思是「喚起未定義的行爲?」 – Rishi

0

我能看到星星。
這是否代之以工作?

class sampleClass 
{ 

    ..... 
    ..... 
    myClass ptr; 
}; 

除非你知道你在做什麼,否則不要使用指針。

1

爲了解決這個問題(一個可能的方式),你必須做出「PTR」實際上指向一個地方MyClass的對象存在ADRESS。爲了存在,你必須創建它,例如儘管如此,您仍然可以考慮使用C++ 11的unique_ptr或shared_ptr而不是原始指針。