c++ shared_ptr继承内存泄漏



我有一个情况,我有一个shared_ptr的子类的基础。

当shared_ptr去删除指针时,只调用父类析构函数。

父类析构函数是虚拟的,而子类不是,尽管我已经试验过所有的组合。

我在valgrind中有这个程序,它显示在创建对象时在new语句处创建了内存。我知道父类析构函数被调用了,但是子类的却没有被调用。

这是孩子:

class NetworkUserAgent : public bbs::UserAgent
{
friend class Server;
public:
    NetworkUserAgent(boost::asio::io_service &ioService, size_t _szBuffer=512u);
    ~NetworkUserAgent();
    void asyncRead();
    void doneRead(std::shared_ptr< std::vector<char> > pBuf,
                    const boost::system::error_code &error, size_t byTrans);
    void writeTo(const std::string &msg);
    void doneWrite(const boost::system::error_code &error, size_t byTrans);
void close();
private:
    boost::asio::ip::tcp::socket socket_;
    const size_t szBuffer;
};

父:

class UserAgent
{
public:
    //'structors
    UserAgent();
    virtual ~UserAgent();
    //commication
    virtual void writeTo(const std::string &msg)=0;
    std::function<void(std::string&)> dataRead;
    //user management
    void login(AccessLevel _accessLevel, int userId, const std::string &_userName);
    void logout();
    //Accessors
    AccessLevel UserAccessLevel() const;
    const std::string &UserName() const;
    const int &UserId() const;
    bool LoggedIn() const;
    //shared to allow reference to child type
    std::shared_ptr<ContextAgentData> contextAgentData;
private:
    std::string userName;
    int userId;
    AccessLevel accessLevel;
};

用法:

void Server::reset()
{   
    shared_ptr<NetworkUserAgent> client (new NetworkUserAgent(ioService));
    acceptor_.async_accept(client->socket_,
        [=] (const boost::system::error_code &error)
            { this->clientAccepted(client, error); }
        );
}
void Server::clientAccepted(shared_ptr<NetworkUserAgent> client,
                                const boost::system::error_code &error)
{
    if(error) return;
    cout << "[] New client has connected" << endl;
    //Generalise to Network useragent
    shared_ptr<UserAgent> uaClientPtr=client;
    context->receiveUserAgent(uaClientPtr);
    client->asyncRead();
    reset();
}

剩余的代码可以在这里看到。

谢谢。

还请注意上面的代码仍在处理中。

编辑:我错了子析构函数正在被调用,

NetworkUserAgent::~NetworkUserAgent()
{   
    this->close();
} 
void NetworkUserAgent::close()
{
    if(!socket_.is_open()) return; //socket is already closed
    //one or more of these functions are probably redundant  
    cout << "send request" <<endl;
    socket_.shutdown(ip::tcp::socket::shutdown_send);
    cout << "cancel" <<endl;
    socket_.cancel();
    cout <<"close"<<endl;
    socket_.close();
    cout << "done" <<endl;
}

编辑:我做了更多的测试,恐怕问题比我想象的要复杂。当项目被销毁时,析构函数被调用,然而,问题是一旦UserAgent进入系统,它就不会被销毁。

如果对useragent来说shared_ptr的几个容器有区别,当一个容器是destroy时,里面元素的析构函数是否被调用?

请让我知道我还能提供什么来解决这个问题。

在UserAgent中有一个dataRead std::函数,它最终被设置为一个lambda,其中包含一个std::shared_ptr来阻止它自毁。我添加了一个close()方法,并将std::函数设置为默认值。

现在一切都好了,它删除好

谢谢你的帮助

我怀疑您的对象正在被切片,尽管我没有测试的环境。

试试这些:

shared_ptr<UserAgent> uaClientPtr = boost::static_pointer_cast<UserAgent>(client);
shared_ptr<UserAgent> uaClientPtr = boost::dynamic_pointer_cast<UserAgent>(client);

void Server::reset()中,auto_ptr就足够了。

在第二种情况下,我将执行以下操作:

void Server::clientAccepted(shared_ptr<NetworkUserAgent> client, const boost::system::error_code error)
{
  if(error) return;
  cout << "[] New client has connected" << endl;
  context->receiveUserAgent(client);
  client->asyncRead();
  this->reset();
}

最新更新