代码之家  ›  专栏  ›  技术社区  ›  Shrouk Khan

cpp删除旧指针并重新初始化

  •  0
  • Shrouk Khan  · 技术社区  · 12 年前

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

    我想知道这样做是否正确?基本上,要点是删除指针并重新创建它。这样做的最佳方法是什么?

    5 回复  |  直到 12 年前
        1
  •  5
  •   MSalters    12 年前

    只需使用 std::unique_ptr<> :

    session.reset(new TcpServerSession(io_service_));

    它做得很好:在新对象可用之前不要删除旧对象,永远不要让会话指向无效对象,即使出现异常,也不会泄露内存。

        2
  •  4
  •   BoBTFish    12 年前
    if (session) { // check if there is any older session, if so..delete them
        session = NULL;
        delete session;
    }
    

    这是完全错误的!你一片空白 session ,泄漏当前存在的任何内容,然后 delete NULL ,这完全没有任何作用。

    为了确保异常安全,您不应该 删去 旧会话,直到您成功创建新会话为止。类似这样的内容:

    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 ,可能是用某种智能指针。

        3
  •  2
  •   Daniel Kamil Kozar    12 年前
        session = NULL;
        delete session;
    

    肯定是不正确的。如果您将 session holds(指向由 new ) 之前 使命感 delete 在它上,您实际上会丢失该内存块,从而导致内存泄漏。这个代码没有爆炸的唯一原因是调用 删去 用一个 NULL 保证是一个反对者。

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

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

    这将保证内存被正确释放。

        4
  •  0
  •   Barmar    12 年前

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

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

        5
  •  0
  •   Daniel Daranas    12 年前
    if (session) { // check if there is any older session, if so..delete them
        session = NULL;
        delete session;
    }
    

    这个代码说:

    如果会话指向某个有效对象 (而不是null),则 别指着它 (相反,指向NULL),然后删除会话现在指向的内容,即。 删去 没有什么 .

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

    这个评论是个谎言。