我有一個情況,我有一個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,當一個包含摧毀是內部調用的元素的析構函數?
請讓我知道我可以提供什麼來解決這個問題。
它不是從問題的代碼貼清醒時共享指針應予以刪除。我查看了鏈接中的代碼(順便提一下),那裏的代碼太多了。你能否詳細說明你希望何時刪除共享指針?你怎麼確定孩子的析構函數沒有被調用(它不記錄父類的東西)? – Chad
只是爲了顯示'std :: shared_ptr'正確處理這種情況的簡單示例:http://ideone.com/TRXVu。我不得不第二個乍得關於你是否確定正確的析構函數沒有被調用的問題? –
請提供可複製的可運行代碼來重現問題。切片出現在您已省略的代碼中的某處非常有可能。 –