C++控制台蛇形游戏成员变量顺序引发访问违规问题求助
为什么调整成员变量顺序会引发访问违规错误?
这是一个典型的C++类成员初始化顺序问题,咱们一步步拆解:
核心原因:成员初始化顺序严格遵循声明顺序
在C++中,类的成员变量是按照你在类里声明的顺序进行初始化的,完全不管你写类内初始化赋值的先后。这是很多开发者容易踩的隐形坑!
看你调整后的代码:
class Snake : public Fruit{ private: struct Body{...}; Body* body = new Body[length]; // 先执行这个初始化 // 后面才是length的声明与初始化 const int length = Board::global_x*Board::global_y; // ...其他成员 };
当程序初始化body的时候,length还没有被初始化!它此时的值是内存里的未定义垃圾值(甚至可能是0)。用一个无效的length去执行new Body[length],要么分配了完全错误大小的数组,要么干脆没分配有效内存空间。
而你最初的代码里,length是在body之前声明的:
const int length = Board::global_x * Board::global_y; // 先初始化length Body* body = new Body[length]; // 再用正确的length分配数组
这时候body分配的数组大小完全正确,自然不会出问题。
为什么停止游戏时才触发错误?
你看到的0xC0000005: Access violation reading location 0x00000004错误,本质是程序在访问不属于它的内存区域。当body指向的数组大小错误时,游戏运行过程中可能因为蛇身较短暂时没触发越界,但停止游戏时通常需要遍历整个蛇身、清理内存资源,这时候就会访问到数组之外的非法内存,直接触发访问违规。
怎么修复?
最简单的修复就是把length的声明移到body之前,确保初始化body时length已经有了正确的值:
class Snake : public Fruit{ private: const int length = Board::global_x*Board::global_y; // 先声明并初始化length struct Body{ int body_pos[2]; // position of every element of snakes body Body* higherEl; // point element nearer head element }; Body* body = new Body[length]; // 现在用的是正确的length值 // 其他成员保持原有顺序即可 int head; short dir_x; //-1 (left or down) / +1 (right or up) short dir_y; friend class Game; int base_length = 3; // base length of snake on start of the game int prev_tailPos[2]; // previous tail position (end of snake) int tail; // tail is sum of base_length and score int time = 100; // delay for snake };
另外,建议养成一个稳妥的编码习惯:
- 尽量让成员变量的声明顺序和初始化顺序保持一致(不管是类内初始化还是构造函数初始化列表)
- 对于依赖其他成员的变量,一定要确保被依赖的成员先声明
内容的提问来源于stack exchange,提问作者Tojmak
相关产品推荐
相关产品推荐

