結構

2015-08-08 52 views
-2
上的訪問衝突

我收到「訪問衝突讀取位置0x0000000000000008」。與此代碼:結構

main.xcpp

Penguin::Game game; 
game.memory = {}; 
game.memory.permanentSize = 1024*64; 
game.memory.permanent = VirtualAlloc(0, game.memory.permanentSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 
game.Start(); 

game.Start()

input = (Input *)memory.permanent; 
*input = {}; // << Access violation reading location. 

遊戲結構

struct Game 
{ 
    struct Memory 
    { 
     uint64 permanentSize; 
     void *permanent; 
    }; 

    Memory memory; 

    Input *input; 

    void Start(); 
}; 

不過。如果我嘗試:

int *i = (int *)memory.permanent; 
*i = 10; 

它的工作原理。

我在做什麼錯了?

+4

你有一個調試器,學習如何使用它! –

回答

1

您在使用VirtualAlloc分配的未初始化內存上正在使用Input類的賦值運算符。這是造成這次事故的原因。賦值運算符通常期望Input對象位於其左側大小的有效狀態。您傳遞的是完全未初始化的原始內存塊,這會觸發未定義的行爲。

賦值運算符總是假定左側包含舊數據,在將新數據存儲在其位置之前,一般情況下必須以某種方式處理舊數據。但在你的情況下,左邊的操作數包含垃圾。試圖使用「正常」方法銷燬垃圾會導致崩潰。您的通話堆棧顯示您的Input內有std::mapstd::map::clear()是什麼崩潰。

換句話說,你在做什麼就相當於這個

std::map<int, int> *p = (std::map<int, int> *) malloc(sizeof *p); 
p->clear(); 

以上,也將導致不確定的行爲(崩潰,最有可能的),因爲它在你的代碼崩潰同樣的原因。

不要嘗試在原始存儲器上使用賦值運算符(以及任何其他非平凡的方法或操作),即在未構造的對象上。

如果你想在*input使用賦值運算符,你必須首先建立在內存中的 有效Input對象。放置新的可以幫助你用它

input = new (memory.permanent) Input{}; 

現在*input是一個有效的,正確構造分配Input類型的對象,這也將循規蹈矩的左側(或任何一邊)

*input = {}; // OK 

實際上,上面的新表達式也會做你正在試圖用你的賦值操作符做的事情,這意味着在那個賦值中不再需要了。

+0

它工作完美。非常感謝您提供這些信息。 –