2013-06-21 68 views
0

在執行一些現有代碼的重寫以更好地流化線時,我在測試期間遇到了崩潰,我縮小到內存對齊問題,但我不知道如何解決它沒有掩蓋問題。有沒有我可能需要的編譯器原語。內存對齊導致使用Visual C++崩潰

我正在使用Microsoft Visual Studio 2008.

我有兩個文件。

FileA.cpp

class ClassA : public baseClass 
{ 
public: 
A() throw(); 
~A() throw(); 

virtual int Init() throw(); 
virtual int Start() throw(); 
virtual int Stop() throw(); 
virtual void Cleanup() throw(); 

public: 
int *pap; 
HANDLE m_evTimerStop; 
    unsigned char m_ctrl; 
CAtlList<int> m_list; 
} 

在FileA.cpp,當我訪問m_list,一切都很好。

在FileB.cpp我已經聲明瞭一個全局變量

extern ClassA g_pCA; 

所以,如果某些功能去訪問m_list:

g_pCA-> m_list.RemoveAt(POS);

它崩潰。如果我打電話: g_pCA-> m_list.GetCount();

在FileA中,計數將是正確的數字,比如10個元素。但是在FileB中,count是一些隨機的大數,有時候是負數。你得到的照片。

所以我設法跟蹤這個事實,例如,文件A.cpp中的m_list在地址0x9caba5,但在文件B.cpp中,m_list在0x9caba8。有一個3字節的差異,這讓我懷疑內存對齊。

如果我將m_list移到m_ctrl的上方,問題就會消失,並且地址在文件之間匹配。

或者,如果我再次將m_ctrl從無符號char更改爲int,問題顯然是由於對齊而固定的。

我不明白爲什麼編譯器在不同的文件中應用不同的內存對齊規則。

任何編譯器標誌來解決這個問題?

謝謝....荷銀

+3

你不會碰巧擁有'雜注包(1)'在你的頭文件中的某處,有沒有機會?這不包括在其他頭部? –

+1

事實上,我很確定「FileA.cpp」確實有一個'#pragma pack(1)'包含在某處,並沒有包含在「FileB.cpp」中 –

回答

1

假設我的猜測約#pragma pack是正確的,解決的辦法是做這樣的事情「只包是真的需要它的結構」:

#pragma pack(push) 
#pragma pack(1) 
struct something_that_needs_to_be_packed 
{ 
    .... 
}; 
#pragma pack(pop) 

現在您需要打包的數據將會如此,但其他數據結構不會受到影響。這就是你想要的,因爲包裝和沒有對齊的數據是一個壞主意,有幾個原因,包括性能,在多線程系統中可靠地使用數據的能力等。

+0

謝謝你的提示。我對一些.h文件進行了一些重構,以解決循環包含的問題,並且在解決方案中,loe,看到有一個#pragma(push,1),我用一個結構取出了它,但流行音樂被留下了。 –