Thread 1: EXC_BAD_ACCESS错误排查:C++玩家手牌赋值失败
解决玩家手牌分配的EXC_BAD_ACCESS错误
嘿,我来帮你搞定这个内存访问错误!你遇到的Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)问题,核心原因是你在操作一个空的vector时直接用索引赋值,导致了越界访问。
错误根源
你的Player类里的hand向量,在构造函数刚初始化的时候是完全空的(默认构造的vector大小为0)。但你在循环里直接写hand[x] = allCards.back();,这就相当于去访问一个根本不存在的内存位置——因为hand还没有为这7个元素分配空间,自然会触发内存访问错误。
两种修复方案
这里有两种简单有效的修复方式,你可以根据习惯选一种:
方案1:用push_back()添加元素(推荐)
直接把赋值语句换成push_back(),它会自动在hand的末尾添加新元素,同时帮你管理内存分配,完全避免越界问题:
Player::Player() { std::random_device seed; std::mt19937 rng(seed()); // 生成完整牌组 for (int i = 1; i <= 13; i++) { Card c1('D', i), c2('C', i), c3('H', i), c4('S', i); allCards.push_back(c1); allCards.push_back(c2); allCards.push_back(c3); allCards.push_back(c4); } // 洗牌 shuffle(std::begin(allCards), std::end(allCards), rng); // 分配7张手牌 for (int x = 0; x < 7; x++) { hand.push_back(allCards.back()); // 替换为push_back,自动添加元素 allCards.pop_back(); } }
方案2:提前初始化hand的大小
如果你更习惯用索引赋值,可以先调用resize()把hand的大小设为7,这样每个索引位置都有合法的内存空间:
Player::Player() { std::random_device seed; std::mt19937 rng(seed()); hand.resize(7); // 提前为7张手牌分配空间 // 生成完整牌组 for (int i = 1; i <= 13; i++) { Card c1('D', i), c2('C', i), c3('H', i), c4('S', i); allCards.push_back(c1); allCards.push_back(c2); allCards.push_back(c3); allCards.push_back(c4); } // 洗牌 shuffle(std::begin(allCards), std::end(allCards), rng); // 分配7张手牌 for (int x = 0; x < 7; x++) { hand[x] = allCards.back(); allCards.pop_back(); } }
额外要注意的小问题
你还需要补全Card类的默认构造函数——因为方案2里的resize(7)会调用Card的默认构造函数,而你现在只声明了Card();却没实现。可以这么补:
// 在类外实现默认构造函数 Card::Card() : face(0), suit('\0') {}
或者直接在类内用默认构造:
class Card { private: int face = 0; char suit = '\0'; // 类内初始化成员变量 public: Card() = default; // 使用编译器生成的默认构造函数 Card(char, int); // ... 其他成员函数 };
另外别忘了包含必要的头文件:<vector>、<algorithm>、<random>,否则代码可能编译不过哦。
内容的提问来源于stack exchange,提问作者v.pashaliuk
相关产品推荐
相关产品推荐

