You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 21:21:26