0

我有一个 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);
}

我想知道这是否正确完成?基本上要点是删除一个指针并重新创建它。最好的方法是什么?

4

5 回答 5

5

只需使用std::unique_ptr<>

session.reset(new TcpServerSession(io_service_));

它让一切都变得正确:在新对象可用之前不要删除旧对象,永远不要让会话指向无效的东西,即使存在异常也不会泄漏内存。

于 2013-10-10T08:03:37.317 回答
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,可能使用某种智能指针。

于 2013-10-10T07:56:03.990 回答
2
    session = NULL;
    delete session;

肯定是不正确的。如果在调用它之前session替换保存的值(指向由 分配的内存块new),您实际上会丢失该内存块,从而导致内存泄漏。这段代码没有崩溃的唯一原因是因为用 a调用保证是无操作的。deletedeleteNULL

因此,您应该将代码替换为以下内容:

    delete session;
    session = NULL; // or nullptr if you've got C++11

这将保证正确释放内存。

于 2013-10-10T07:54:32.870 回答
0

摆脱session = NULL之前delete session。您正在尝试删除空指针。

您不需要将其设置为 null,因为您将立即将其设置为新的 TCP 会话。

于 2013-10-10T07:54:30.713 回答
0
if (session) { // check if there is any older session, if so..delete them
    session = NULL;
    delete session;
}

这段代码说:

如果 session 指向某个有效对象(而不是 null),则停止指向它(而是指向 NULL),然后删除 session 现在指向的内容,即delete nothing

这真是太糟了。这是真正的内存泄漏。

评论是谎言。

于 2013-10-10T07:54:38.093 回答