You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

typedef数组类型不可赋值:Chip8虚拟机内存访问报错解决方案咨询

解决数组类型指针的赋值错误问题

你遇到的问题根源在于**chip8_memory*是指向整个数组的指针**,而不是指向数组元素的指针。当你写m[cs->sp]时,编译器会把它解析为*(m + cs->sp)——也就是偏移cs->sp个chip8_memory大小的内存块,得到的是一个完整的uint8_t[0xfff]数组,而数组类型是不能直接赋值的,这就是报错的核心原因。

下面给你几种既能保留chip8_memory类型语义,又能正常读写内存的解决方案:

方案1:解引用数组指针后访问元素

既然m是指向整个数组的指针,那我们先通过*m拿到数组本身,再用下标访问元素即可。这种方式完全保留你原有的类型定义:

void chip8_2nnn(const chip8_opcode oc, chip8_cpu_state* cs, chip8_memory* m) {
    (*m)[cs->sp] = cs->pc & 0xff;
    (*m)[cs->sp + 1] = cs->pc >> 8;
    cs->sp -= 2;
    cs->pc = nnn(oc);
}

对应的最小复现示例修改后:

TEST(foo, bar) {
    typedef int foo[3];
    foo bar = {1, 2, 3};
    foo* baz = &bar;
    bar[2] = 5;
    (*baz)[2] = 5; // 添加解引用操作,即可正常赋值
}

方案2:定义指向内存元素的指针类型

如果你觉得每次写(*m)有点繁琐,可以额外定义一个指向内存元素的指针类型,既保留语义又简化代码:

// 保留原内存数组类型定义
typedef uint8_t chip8_memory[0xfff];
// 新增指向内存元素的指针类型,明确它是内存的指针
typedef uint8_t* chip8_memory_ptr;

void chip8_2nnn(const chip8_opcode oc, chip8_cpu_state* cs, chip8_memory_ptr m) {
    m[cs->sp] = cs->pc & 0xff;
    m[cs->sp + 1] = cs->pc >> 8;
    cs->sp -= 2;
    cs->pc = nnn(oc);
}

调用时直接传递数组名即可(数组名会隐式转换为指向第一个元素的指针):

chip8_memory mem;
chip8_2nnn(opcode, &cpu_state, mem);

方案3:用结构体封装数组(推荐,语义最清晰)

如果想彻底避免数组指针的混淆,同时让chip8_memory的语义更明确,可以把数组封装到结构体里:

typedef struct {
    uint8_t data[0xfff];
} chip8_memory;

void chip8_2nnn(const chip8_opcode oc, chip8_cpu_state* cs, chip8_memory* m) {
    m->data[cs->sp] = cs->pc & 0xff;
    m->data[cs->sp + 1] = cs->pc >> 8;
    cs->sp -= 2;
    cs->pc = nnn(oc);
}

这种方式的优势很明显:

  • chip8_memory的语义非常直观,就是一个虚拟机内存的容器
  • 访问元素时通过->data清晰表明操作的是内存数据
  • 结构体指针的行为符合直觉,不会出现数组指针的偏移歧义

内容的提问来源于stack exchange,提问作者user840413

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:33:38