结构

2015-08-08 54 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

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