私は、子クラスの基底にshared_ptrがある状況があります。C++ shared_ptr継承メモリリーク
shared_ptrがポインタを削除すると、親デストラクタだけが呼び出されます。
私はすべての組み合わせで実験しましたが、親デストラクターは仮想ですが、子はありません。
私はvalgrindでプログラムを持っており、オブジェクトが作成されたときに新しいステートメントでメモリが作成されることを示しています。私は親のデストラクタが呼び出されていることを知っていますが、子の子はありません。
これは子供である:
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();
}
The rest of the code can be seen here。
ありがとうございます。
上記のコードはまだ処理中です。
編集:私は、子供のデストラクタが呼び出されている間違っていた
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が破棄されないシステムに入ると問題になります。何かが破壊されるのを止めている。
shared_ptrのいくつかのコンテナがuseragentになっている場合は、containsが破壊されたときに、内部の要素のデストラクタが呼び出されますか?
問題を解決するために他に何ができるのか教えてください。
。私はあなたのリンクのコードを見ました(途中で眉をすませています)。あなたは、共有ポインタが削除されることを期待するときに詳しく説明できますか?子供のデストラクタが呼び出されていないことを確認してください(親のようなことは記録しません)。 – Chad
'std :: shared_ptr'がそのような状況を正しく処理することを示す単純な例です:http://ideone.com/TRXVu。私はあなたが正しいデストラクタが呼び出されていないかどうかについてチャドの質問を二番目にしなければならないのですか? –
問題を再現するコンパイル可能な実行可能コードを提供してください。あなたが省略したコードのどこかでスライシングが行われる可能性が非常に高いです。 –