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

实现C++状态机时遭遇double free错误,请求问题排查指导

C++状态机实现中的double free错误排查求助

我在为一项任务用C++实现状态机,计划维护一个Context对象,它包含:

  • 用于跟踪当前状态的state_对象
  • 用于触发状态切换的TransitionTo()方法

编写示例实现并测试时遇到了double free错误,希望社区帮忙排查问题。

代码实现

#include <iostream>
#include <string>

class State;

/* Context class and method implementation */
class Context
{
    State* state_;
public:
    explicit Context(State* state);
    void TransitionTo(State* newState);
};

Context::Context (State* state): state_ (nullptr) 
{
    this->TransitionTo(state);
}

void Context::TransitionTo(State* newState)
{
    std::cout <<"Requesting state transition to " << newState->stateName<<"\n";
    std::string previous_state_name = "None";
    if (this->state_ != nullptr)
    {
        previous_state_name = this->state_->stateName;
        delete this->state_;
    }
    this->state_ = newState;
    std::cout << "State changed from "<< previous_state_name << " to "<< this->state_->stateName << "\n";
    this->state_->set_context(this);
}



/* State class and method implementation */
class State
{
    protected:
        Context* context_;
    public:
        std::string stateName;
        void set_context(Context* newContext);
        virtual ~State();
        
};

State::~State()
{
    std::cout << stateName <<" state deleted \n";
    delete context_ ;
}

void State::set_context(Context *newContext) 
{
    this->context_ = newContext;
}


/* Declaring different states which are derived from State */
class HappyState : public State
{
public:
    HappyState();
};

HappyState::HappyState()
{
    stateName = "Happy";
}

class NeutralState : public State
{
public:
    NeutralState();
};

NeutralState::NeutralState()
{
    stateName = "Neutral";
}

class SadState : public State
{
public:
    SadState();
};

SadState::SadState()
{
    stateName = "Sad";
}

/* Test the implementation */
int main()
{
    Context* ctx  = new Context(( new NeutralState()));
    
    ctx->TransitionTo(new HappyState());
    
    ctx->TransitionTo(new SadState());

    return 0;
}

运行输出

Requesting state transition to Neutral
State changed from None to Neutral
Requesting state transition to Happy
Neutral state deleted 
State changed from Neutral to Happy
Requesting state transition to Sad
Happy state deleted 
State changed from Happy to Sad
Sad state deleted 
free(): double free detected in tcache 2
Aborted (core dumped)

问题根源与修复

问题原因

  1. 所有权混乱导致重复释放:State类的析构函数中调用了delete context_;,但Context对象是在main函数中通过new创建的,其生命周期应由main管理,而非State对象。当状态切换时,旧State被Context::TransitionTo销毁,此时State的析构函数会错误释放Context;后续程序中Context仍被使用,最终程序结束时可能再次尝试释放Context,触发double free错误。
  2. 内存管理职责不清晰:Context持有State指针并负责释放State,但State却持有Context指针并尝试释放它,违反了单一所有权原则。

修复方案

  • 移除State析构函数中对Context的释放:删除State::~State()里的delete context_;语句,因为State不拥有Context的所有权。
  • 手动管理Context的生命周期:在main函数末尾添加delete ctx;,确保Context被正确释放,避免内存泄漏。

修复后的关键代码片段

修改后的State析构函数

State::~State()
{
    std::cout << stateName <<" state deleted \n";
    // 移除delete context_;
}

修改后的main函数

int main()
{
    Context* ctx  = new Context(( new NeutralState()));
    
    ctx->TransitionTo(new HappyState());
    
    ctx->TransitionTo(new SadState());

    delete ctx; // 手动释放Context
    return 0;
}

内容的提问来源于stack exchange,提问作者Kshitij_9192

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 04:25:39