i have a tcp server, which requires to allow exactly one client to connect to it at any time. anytime a new client connects, older session must be deleted and new session created.
我有一个tcp服务器,它需要允许任何时候只有一个客户端连接到它。每当新客户端连接时,必须删除旧会话并创建新会话。
right now, i am doing it like this:
现在,我这样做:
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));
}
so any time i would like to send a msg to the client, it is being done like this:
所以任何时候我想发送一个消息到客户端,它是这样做的:
int TcpServer::sendMsgToClient(std::string msg) {
if (session)
session->sendMsgToClient(msg);
}
i am wondering if this is being done correctly? basically the main point is deleting a pointer and re-creating it.whats the best way to do this?
我想知道这是否正确完成?基本上主要是删除一个指针并重新创建它。这是最好的方法吗?
5 个解决方案
#1
4
if (session) { // check if there is any older session, if so..delete them
session = NULL;
delete session;
}
This is totally wrong! You blank out session
, leaking whatever is currently there, and then delete
NULL
, which does absolutely nothing.
这是完全错误的!你清空会话,泄漏当前存在的任何内容,然后删除NULL,这绝对没有。
To be exception safe, you should not delete
the old session until you have successfully created the new one. Something like this:
为了安全异常,在成功创建新会话之前,不应删除旧会话。像这样的东西:
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.
}
Actually, this assumes async_accept
doesn't throw. If it can, you will need to be careful to delete the newSession
, probably with some kind of smart pointer.
实际上,这假设async_accept不抛出。如果可以的话,你需要小心删除newSession,可能还有一些智能指针。
#2
5
Just use a std::unique_ptr<>
:
只需使用std :: unique_ptr <>:
session.reset(new TcpServerSession(io_service_));
session.reset(new TcpServerSession(io_service_));
It gets everything right: don't delete old object before a new one is available, never have session point to something invalid, and even in the presence of exceptions no memory is leaked.
它使一切正确:在新对象可用之前不要删除旧对象,永远不要让会话指向无效的对象,即使存在异常,也不会泄漏内存。
#3
2
session = NULL;
delete session;
Is most certainly not correct. If you replace the value that session
holds (which points to a block of memory allocated by new
) before calling delete
on it, you effectively lose that block of memory, causing a memory leak. The only reason why this code doesn't blow up is because calling delete
with a NULL
is guaranteed to be a no-op.
肯定是不正确的。如果在调用delete之前替换会话所持有的值(指向由new分配的内存块),则实际上会丢失该内存块,从而导致内存泄漏。这个代码没有爆炸的唯一原因是因为使用NULL调用delete肯定是no-op。
Thus, you should replace the code with the following :
因此,您应该使用以下代码替换代码:
delete session;
session = NULL; // or nullptr if you've got C++11
Which will guarantee that the memory is properly freed.
这将保证内存被正确释放。
#4
0
Get rid of session = NULL
before delete session
. You're trying to delete the null pointer.
在删除会话之前删除session = NULL。您正在尝试删除空指针。
You don't need to set it to null because you're immediately going to set it to the new TCP session.
您不需要将其设置为null,因为您将立即将其设置为新的TCP会话。
#5
0
if (session) { // check if there is any older session, if so..delete them
session = NULL;
delete session;
}
This code says:
这段代码说:
If session points to some valid object (instead of being null), then stop pointing to it (instead, point to NULL), and then delete what session now points to, i.e. delete nothing.
如果会话指向某个有效对象(而不是null),则停止指向它(而不是指向NULL),然后删除现在指向的会话,即不删除任何内容。
This is very bad. It is a genuine memory leak.
这真是太糟了。这是一个真正的内存泄漏。
The comment is a lie.
评论是谎言。
#1
4
if (session) { // check if there is any older session, if so..delete them
session = NULL;
delete session;
}
This is totally wrong! You blank out session
, leaking whatever is currently there, and then delete
NULL
, which does absolutely nothing.
这是完全错误的!你清空会话,泄漏当前存在的任何内容,然后删除NULL,这绝对没有。
To be exception safe, you should not delete
the old session until you have successfully created the new one. Something like this:
为了安全异常,在成功创建新会话之前,不应删除旧会话。像这样的东西:
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.
}
Actually, this assumes async_accept
doesn't throw. If it can, you will need to be careful to delete the newSession
, probably with some kind of smart pointer.
实际上,这假设async_accept不抛出。如果可以的话,你需要小心删除newSession,可能还有一些智能指针。
#2
5
Just use a std::unique_ptr<>
:
只需使用std :: unique_ptr <>:
session.reset(new TcpServerSession(io_service_));
session.reset(new TcpServerSession(io_service_));
It gets everything right: don't delete old object before a new one is available, never have session point to something invalid, and even in the presence of exceptions no memory is leaked.
它使一切正确:在新对象可用之前不要删除旧对象,永远不要让会话指向无效的对象,即使存在异常,也不会泄漏内存。
#3
2
session = NULL;
delete session;
Is most certainly not correct. If you replace the value that session
holds (which points to a block of memory allocated by new
) before calling delete
on it, you effectively lose that block of memory, causing a memory leak. The only reason why this code doesn't blow up is because calling delete
with a NULL
is guaranteed to be a no-op.
肯定是不正确的。如果在调用delete之前替换会话所持有的值(指向由new分配的内存块),则实际上会丢失该内存块,从而导致内存泄漏。这个代码没有爆炸的唯一原因是因为使用NULL调用delete肯定是no-op。
Thus, you should replace the code with the following :
因此,您应该使用以下代码替换代码:
delete session;
session = NULL; // or nullptr if you've got C++11
Which will guarantee that the memory is properly freed.
这将保证内存被正确释放。
#4
0
Get rid of session = NULL
before delete session
. You're trying to delete the null pointer.
在删除会话之前删除session = NULL。您正在尝试删除空指针。
You don't need to set it to null because you're immediately going to set it to the new TCP session.
您不需要将其设置为null,因为您将立即将其设置为新的TCP会话。
#5
0
if (session) { // check if there is any older session, if so..delete them
session = NULL;
delete session;
}
This code says:
这段代码说:
If session points to some valid object (instead of being null), then stop pointing to it (instead, point to NULL), and then delete what session now points to, i.e. delete nothing.
如果会话指向某个有效对象(而不是null),则停止指向它(而不是指向NULL),然后删除现在指向的会话,即不删除任何内容。
This is very bad. It is a genuine memory leak.
这真是太糟了。这是一个真正的内存泄漏。
The comment is a lie.
评论是谎言。