结构访问冲突
Access violation on struct
我正在使用此代码获得 "Access violation reading location 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;
有效。
我做错了什么?
您在使用 VirtualAlloc
分配的未初始化内存上使用 Input
class 的赋值运算符。这就是导致崩溃的原因。赋值运算符通常期望 Input
对象处于 有效状态 的左侧大小。您正在传递一块完全未初始化的原始内存,这会触发未定义的行为。
赋值运算符总是假定左侧包含旧数据,在一般情况下,在将新数据存储到它的位置之前必须以某种方式处理旧数据。但在您的情况下,左侧操作数包含垃圾。尝试使用 "normal" 方法销毁该垃圾会导致崩溃。您的调用堆栈显示您的 Input
中有一个 std::map
。 std::map::clear()
是崩溃的原因。
换句话说,你所做的相当于这个
std::map<int, int> *p = (std::map<int, int> *) malloc(sizeof *p);
p->clear();
以上也会导致未定义的行为(很可能是崩溃),原因与它在您的代码中崩溃的原因完全相同。
不要尝试在原始内存(即非构造对象)上使用赋值运算符(以及任何其他重要的方法或操作)。
如果你想在 *input
上使用赋值运算符,你必须构造一个
首先是该内存中的有效 Input
对象。 Placement new 可以帮助你
input = new (memory.permanent) Input{};
现在 *input
是一个有效的、正确构造的类型 Input
的对象,它在赋值
的左侧(或任何一侧)也将表现正确
*input = {}; // OK
实际上,上面的 new 表达式也将执行您尝试使用赋值运算符执行的操作,这意味着不再需要该赋值。
我正在使用此代码获得 "Access violation reading location 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;
有效。
我做错了什么?
您在使用 VirtualAlloc
分配的未初始化内存上使用 Input
class 的赋值运算符。这就是导致崩溃的原因。赋值运算符通常期望 Input
对象处于 有效状态 的左侧大小。您正在传递一块完全未初始化的原始内存,这会触发未定义的行为。
赋值运算符总是假定左侧包含旧数据,在一般情况下,在将新数据存储到它的位置之前必须以某种方式处理旧数据。但在您的情况下,左侧操作数包含垃圾。尝试使用 "normal" 方法销毁该垃圾会导致崩溃。您的调用堆栈显示您的 Input
中有一个 std::map
。 std::map::clear()
是崩溃的原因。
换句话说,你所做的相当于这个
std::map<int, int> *p = (std::map<int, int> *) malloc(sizeof *p);
p->clear();
以上也会导致未定义的行为(很可能是崩溃),原因与它在您的代码中崩溃的原因完全相同。
不要尝试在原始内存(即非构造对象)上使用赋值运算符(以及任何其他重要的方法或操作)。
如果你想在 *input
上使用赋值运算符,你必须构造一个
首先是该内存中的有效 Input
对象。 Placement new 可以帮助你
input = new (memory.permanent) Input{};
现在 *input
是一个有效的、正确构造的类型 Input
的对象,它在赋值
*input = {}; // OK
实际上,上面的 new 表达式也将执行您尝试使用赋值运算符执行的操作,这意味着不再需要该赋值。