C++中使用if语句修改指针指向时遇执行异常问题排查
C++指针未初始化导致的执行崩溃问题解决
问题背景
我是C新手,使用g 12.2.0编译器。尝试通过if语句修改指针指向,添加if(a==2){}语句后,代码在*movingPiece处停止执行;注释掉该语句则无异常。试过用switch语句、调整变量赋值位置,都没解决。预期指针能把修改后的变量传入后续代码(比如generateAttackMap),用来验证移动后是否会让玩家处于被将军状态。代码使用uint64_t进行64位整数位运算,相关代码如下:
bool checkMove(int a , uint64_t s , uint64_t e, bool colour, uint64_t board, uint64_t black, uint64_t white, uint64_t pawn, uint64_t king, uint64_t queen, uint64_t bishop, uint64_t knight, uint64_t rook , uint64_t attackMap , uint64_t doubleAttackMap) { uint64_t x ,z , *movingPiece; uint64_t *pieces = &white; board = board &~ s; if (colour){ uint64_t *pieces = &black; } if (a == 0){ //pawn uint64_t *movingPiece = &pawn; *movingPiece = *movingPiece &~ s; } if(a == 1){ //queen uint64_t *movingPiece = &queen; *movingPiece = *movingPiece &~ s; } if(a==2){ uint64_t *movingPiece = &rook; *movingPiece = *movingPiece&~s; } *pieces = *pieces|e; //----------------------------------------Code executes up until this point *movingPiece = *movingPiece|e; //----------------------------------------Code beyond does not execute board = board|e; generateAttackMap(~colour, board, black, white, pawn, king, queen, bishop, knight, rook, &x , &z); if (x & king){ return false; } else{ return true; } }
问题根源
- 指针重定义导致未初始化:函数开头声明的
*movingPiece从未被赋值,而每个if块里的uint64_t *movingPiece = &xxx;是重新定义的局部变量,和外层的movingPiece完全无关。当代码执行到*movingPiece = *movingPiece|e;时,外层指针还是野指针(指向随机内存地址),解引用会触发未定义行为(直接崩溃)。 - 隐藏的
pieces变量重定义问题:if (colour){ uint64_t *pieces = &black; }同样是重定义了新变量,外层的pieces根本不会被修改,导致不管colour是true还是false,操作的都是white变量,这也是一个潜在bug。
修复后的代码
bool checkMove(int a , uint64_t s , uint64_t e, bool colour, uint64_t board, uint64_t black, uint64_t white, uint64_t pawn, uint64_t king, uint64_t queen, uint64_t bishop, uint64_t knight, uint64_t rook , uint64_t attackMap , uint64_t doubleAttackMap) { uint64_t x, z, *movingPiece = nullptr; // 初始化指针为nullptr,避免野指针 uint64_t *pieces = &white; board = board & ~s; // 直接修改外层pieces指针,不要重定义 if (colour){ pieces = &black; } // 给外层movingPiece赋值,不再重定义 if (a == 0){ movingPiece = &pawn; *movingPiece = *movingPiece & ~s; } if(a == 1){ movingPiece = &queen; *movingPiece = *movingPiece & ~s; } if(a == 2){ movingPiece = &rook; *movingPiece = *movingPiece & ~s; } // 检查指针是否有效,避免空指针解引用 if (!movingPiece) { // 处理a不在0-2范围内的情况,比如直接返回false return false; } *pieces = *pieces | e; *movingPiece = *movingPiece | e; board = board | e; generateAttackMap(~colour, board, black, white, pawn, king, queen, bishop, knight, rook, &x, &z); // 简化返回逻辑 return !(x & king); }
关键修复点
- 移除所有if块内的
movingPiece和pieces重定义,直接给外层声明的指针赋值 - 初始化
movingPiece为nullptr,并在解引用前检查指针有效性,避免空指针崩溃 - 简化了返回语句的逻辑,让代码更简洁
内容的提问来源于stack exchange,提问作者Michael Haney
相关产品推荐
相关产品推荐

