2008-12-12 58 views
1

這使我瘋狂。我使用在Windows的.lib,一些第三方的代碼,在調試模式,是造成類似如下的錯誤:無法追蹤潛在的內存覆蓋。窗口奇怪

Run-Time Check Failure #2 - Stack around the variable 'foo' was corrupted. 

將引發錯誤或者當對象超出範圍或被刪除。簡單地分配這些對象之一,然後刪除它會拋出錯誤。因此,我認爲問題出現在許多構造函數/析構函數之一中,但是儘管遍歷了每行代碼,但我無法找到問題所在。

但是,只有在靜態庫中創建這些對象時纔會發生這種情況。如果我在我的EXE應用程序中創建一個,錯誤不會出現。第三方代碼本身位於靜態庫中。例如,此操作失敗:

**3RDPARTY.LIB** 

class Foo : public Base 
{ 
    ... 
}; 

**MY.LIB** 

void Test() 
{ 
    Foo* foo = new Foo; 
    delete foo; // CRASH! 
} 

**MY.EXE** 

void Func() 
{ 
    Test(); 
} 

但是這將工作:

**3RDPARTY.LIB** 

class Foo : public Base 
{ 
    ... 
}; 

**MY.EXE** 

void Func() 
{ 
    Foo* foo = new Foo; 
    delete foo; // NO ERROR 
} 

所以,切割出「中間」的.lib文件使問題消失,正是這種weridness是推動我狂。 EXE和2個庫都使用相同的CRT庫。沒有錯誤鏈接。第三方代碼使用繼承,並且有5個基類。我儘可能多地評論了代碼,同時仍然可以構建代碼,而我只是看不到發生了什麼。

因此,如果有人知道爲什麼.lib中的代碼對.exe中的相同代碼採取不同的行爲,我很樂意聽到它。同上任何提示追蹤內存覆蓋!我正在使用Visual Studio 2008.

回答

2

好的,我追蹤了這個問題,如果有人感興趣的話,它就是一個破解者。基本上,我的.LIB,展示了這個問題。已將_WIN32_WINNT定義爲0x0501(Windows 2000及更高版本),但我的EXE和第三方LIB將其定義爲0x0600(Vista)。現在,由第三方LIB包括在報頭中的一個是sspi.h它定義了一個稱爲SecurityFunctionTable結構,其包括下面的代碼片斷:

#if OSVER(NTDDI_VERSION) > NTDDI_WIN2K 
    // Fields below this are available in OSes after w2k 
    SET_CONTEXT_ATTRIBUTES_FN_W   SetContextAttributesW; 
#endif // greater thean 2K 

釷切總而言之,這意味着在之間的對象大小的不匹配LIB和這導致運行時檢查失敗。

Class!

0

您的.lib文件是否與庫的.lib鏈接?我從你的例子中假設你包含了析構函數聲明的頭文件;沒有它,刪除這種類型是允許的,但可能導致UB(以一種奇怪的方式違背一般規則,即在使用之前必須定義某些事物)。如果.lib文件沒有鏈接在一起,有可能是自定義的operator delete或析構函數有一些奇怪的鏈接問題,雖然不應該發生,但你永遠無法完全知道它不會。

2

一種可能性是它的calling convention不匹配 - 確保您的庫和可執行文件都設置爲使用相同的默認調用約定(通常爲__cdecl)。要設置,請打開項目屬性並轉至配置屬性> C/C++>高級並查看呼叫公約選項。如果你使用錯誤的調用約定調用一個函數,你會完全搞砸堆棧。

+0

所有的項目都使用__cdecl。崩潰只發生在創建特定類型的對象時 - 其他對象工作正常。 – Rob 2008-12-12 16:58:02

0

沒有看到更多的代碼,很難給你一個確定的答案。但是,爲了追蹤內存覆蓋,我推薦使用WinDbg(免費從Microsoft搜索「Debugging Tools for Windows」)。

當你將它連接到你的進程時,你可以讓它爲內存訪問設置斷點(讀,寫或執行)。它總體上非常強大,但它應該特別幫助你。

0

當對象超出範圍或被刪除時,將引發該錯誤。

每當我遇到這個問題時,它必須使用與應用程序的其餘部分不同版本的C++運行庫編譯的庫。