C++自定义DoubleStack动态栈复制后等价判断错误排查
问题原因
你遇到的栈等价判断错误是多处代码逻辑缺陷共同导致的,核心问题如下:
operator==重载存在严重逻辑错误:当栈为空(tos=0)时for循环不会执行,函数没有返回值,属于未定义行为,会随机返回真值触发错误的相等判定;且原有循环逻辑仅对比第一个元素就直接返回结果,完全没有校验两个栈的元素数量是否一致,只要第一个元素相等就会误判两栈相等。- 拷贝构造函数实现为浅拷贝,仅复制指针地址没有开辟新的堆内存,两个对象会共享同一块存储区,析构时会触发重复释放内存的崩溃问题。
operator=赋值运算符漏拷贝noi(元素计数)成员变量,且没有添加自赋值判断,出现自赋值场景时会直接访问已释放的野指针。pop函数逻辑错误:没有正确将栈顶元素赋值给传出参数,且存在不可达的return语句,返回值不符合设计预期。
修复方案
1. 修正头文件声明
给只读接口的参数和函数加上const修饰,修正push函数的参数传递方式:
#include <iostream> class DoubleStack { public: DoubleStack(size_t capacity); DoubleStack(const DoubleStack& rhs); ~DoubleStack(void); DoubleStack& operator=(const DoubleStack& rhs); int push(double item); int pop(double& item); int empty(void); size_t capacity(void); size_t size(void); int operator==(const DoubleStack& rhs) const; friend std::ostream& operator<< (std::ostream &output, const DoubleStack& s); private: double *data; size_t stack_size; size_t tos; size_t noi; };
2. 修正类实现文件的错误逻辑
拷贝构造函数改为深拷贝
DoubleStack::DoubleStack(const DoubleStack& rhs) { stack_size = rhs.stack_size; tos = rhs.tos; noi = rhs.noi; data = new double[stack_size]; for (size_t i = 0; i < tos; i++) { data[i] = rhs.data[i]; } }
重写相等判断逻辑
int DoubleStack::operator==(const DoubleStack& rhs) const { // 元素数量不同直接判定不等 if (noi != rhs.noi) { return false; } // 逐个对比所有元素,全部相等才返回真 for (size_t i = 0; i < tos; i++) { if (data[i] != rhs.data[i]) { return false; } } return true; }
修正赋值运算符
DoubleStack& DoubleStack::operator=(const DoubleStack& rhs) { // 自赋值直接返回 if (this == &rhs) { return *this; } delete[] data; stack_size = rhs.stack_size; tos = rhs.tos; noi = rhs.noi; data = new double[stack_size]; for (size_t i = 0; i < tos; i++) { data[i] = rhs.data[i]; } return *this; }
修正pop函数逻辑
int DoubleStack::pop(double& item) { if (empty() == true) { std::cout<<"Cannot remove number because stack is empty."<<std::endl; return 0; } noi--; tos--; item = data[tos]; std::cout<<"Removed "<<item<<std::endl; return 1; }
补全push函数返回值类型
int DoubleStack::push(double item) { if (noi >= stack_size) { std::cout<<"Stack size at capacity. Cannot push."<<std::endl; return 0; } noi++; data[tos++] = item; std::cout<<"Inserted "<<item<<std::endl; return 1; }
其余成员函数(构造函数、析构函数、empty、capacity、size、流运算符)原有逻辑可正常工作,无需修改。
内容的提问来源于stack exchange,提问作者JCPowell
相关产品推荐
相关产品推荐

