使用链表栈模拟队列时调用front/back触发断言失败问题排查
问题分析与修复方案
核心报错原因
1. 最可能的触发点:ClientNode 构造导致指针悬空
你在 push 方法中构造 ClientNode 时传入的是 const Client& 类型参数,如果 ClientNode 内部存储的是 Client* 指针,且构造时直接取了该引用的地址,当参数生命周期结束后,指针就会变为悬空指针。调用 front()/back() 时解引用这个悬空指针会直接触发内存访问错误,不会走到断言执行步骤。
正确的 ClientNode 实现应该直接存储 Client 对象拷贝而非指针,同时显式初始化 next 指针:
class ClientNode { private: Client client; ClientNode* next; public: ClientNode(const Client& c) : client(c), next(nullptr) {} Client* getClient() { return &client; } ClientNode* getNext() { return next; } void setNext(ClientNode* n) { next = n; } };
2. 未初始化 next 指针
如果 ClientNode 构造时没有显式将 next 指针赋值为 nullptr,新节点的 next 会是野指针,后续链表操作时可能触发非法内存访问。
3. 异常未被捕获
如果你的测试框架没有适配自定义的 EmptyList 异常,front()/back() 抛出异常时会直接终止测试,表现为断言执行前报错,可以在测试代码中增加异常捕获逻辑验证。
4. 实现不符合需求
你当前贴出的 ClientList 是直接实现的链表队列,不符合老师要求的「用链表栈模拟队列」的要求。标准的栈模拟队列需要两个链表栈实现:
- 入队操作统一push到入栈
- 调用
front()/pop()时,如果出栈为空,就把入栈的所有元素依次弹出并push到出栈,再操作出栈的栈顶即可。
现有代码优化点
Client 类的 == 运算符重载可以简化为单层逻辑,无需多层嵌套判断:
bool Client::operator==(const Client& clientCoteDroit) const { return clientID == clientCoteDroit.clientID && firstName == clientCoteDroit.firstName && surName == clientCoteDroit.surName; }
内容的提问来源于stack exchange,提问作者Nicolas Pellerin
相关产品推荐
相关产品推荐

