结构上的访问冲突

时间:2015-08-08 18:03:15

标签: c++ pointers memory struct access-violation

我的访问违规读取位置为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;

有效。

我做错了什么?

1 个答案:

答案 0 :(得分:1)

您正在使用Input分配的未初始化内存上使用VirtualAlloc类的赋值运算符。这就是导致崩溃的原因。赋值运算符通常需要左侧大小的有效状态中的Input对象。您正在传递一块完全未初始化的原始内存,这会触发未定义的行为。

赋值运算符始终假定左侧包含旧数据,在将数据存储到其位置之前,通常必须以某种方式处理旧数据。但在你的情况下,左侧操作数包含垃圾。试图使用“正常”方法销毁垃圾会导致崩溃。您的调用堆栈显示您的std::map内有Inputstd::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

实际上,上面的new-expression也会用你的赋值运算符做你想做的事情,这意味着不再需要那个赋值。