我有一个tcp服务器,它需要允许任何时候只有一个客户端连接到它。每当新客户端连接时,必须删除旧会话并创建新会话。
现在,我这样做:
void TcpServer::start_accept() {
Logger::info("[TCPSERVER] TCP Server starting to accept", __LINE__, __FILE__);
if (session) { // check if there is any older session, if so..delete them
session = NULL;
delete session;
}
session = new TcpServerSession(io_service_);
acceptor_.async_accept(session->socket(), boost::bind(&TcpServer::handle_accept, this, session, boost::asio::placeholders::error));
}
所以任何时候我想向客户端发送一个消息,它都是这样做的:
int TcpServer::sendMsgToClient(std::string msg) {
if (session)
session->sendMsgToClient(msg);
}
我想知道这是否正确完成?基本上主要是删除一个指针并重新创建它。这是最好的方法吗?
答案 0 :(得分:5)
只需使用std::unique_ptr<>
:
session.reset(new TcpServerSession(io_service_));
它使一切正常:在新对象可用之前不要删除旧对象,永远不要让会话指向无效的对象,即使存在异常,也不会泄漏内存。
答案 1 :(得分:4)
if (session) { // check if there is any older session, if so..delete them
session = NULL;
delete session;
}
这是完全错误的!您将session
空白,泄露当前存在的任何内容,然后delete
NULL
,这绝对没有任何内容。
为了安全起见,在成功创建新会话之前,不应该delete
旧会话。像这样:
if (session) {
// Create and initialise the new session first
TcpServerSession* newSession = new TcpServerSession(io_service_);
// Don't know what this line does, but I assume it's important
acceptor_.async_accept(newSession->socket(), boost::bind(&TcpServer::handle_accept, this, newSession, boost::asio::placeholders::error));
std::swap(session, newSession); // Put the new one in place
delete newSession; // delete the old one.
}
实际上,这假定async_accept
不会抛出。如果可以的话,你需要小心删除newSession
,可能还有某种智能指针。
答案 2 :(得分:2)
session = NULL;
delete session;
肯定不正确。如果在上调用session
之前替换new
占有的值(指向由delete
分配的内存块),则实际上会丢失该块内存,导致内存泄漏。此代码不会爆炸的唯一原因是因为delete
调用NULL
可以保证是无操作。
因此,您应该使用以下代码替换代码:
delete session;
session = NULL; // or nullptr if you've got C++11
这将保证正确释放内存。
答案 3 :(得分:0)
在session = NULL
之前摆脱delete session
。您正在尝试删除空指针。
您不需要将其设置为null,因为您将立即将其设置为新的TCP会话。
答案 4 :(得分:0)
if (session) { // check if there is any older session, if so..delete them
session = NULL;
delete session;
}
此代码说:
如果会话指向某个有效对象(而不是null),则停止指向它(而不是指向NULL),然后立即删除会话指向,即删除没有 。
这非常糟糕。这是真正的内存泄漏。
评论是谎言。