PDA

View Full Version : Memory leak in Qsocketserver



creatron
3rd March 2016, 19:02
I used valgrind to locate memory leaks .
I use the standard QT socket

/** ---------------------------------------------------------------------------
* @brief socket_client::socket_client Constructor
*/
socket_client::socket_client(void)
{
queue_array = new (QByteArray);
socket_connected = false;
tcp_socket = new QTcpSocket(this);
disconnect(tcp_socket ,0 ,0 ,0);

connect(&my_heartbeat_timer, SIGNAL(timeout()), this, SLOT(slot_heartbeat_timer()));
change_state = true;
my_port = 0;
}
/** ---------------------------------------------------------------------------
* @brief socket_client::~socket_client Destructor
*/
socket_client::~socket_client(void)
{
if (queue_array != NULL) delete queue_array;
if (tcp_socket != NULL) tcp_socket->deleteLater();
}


The code with " if(tcp_socket->waitForConnected(200))" is highlighted by valgrind.


/** ---------------------------------------------------------------------------
* @brief socket_client::connect_to_server
* @param ip_address
* @param port
*/
BOOL socket_client::connect_to_server(const char * ip_address,
const UINT_32 & port)
{
change_state = socket_connected;
my_ip_address = ip_address;
my_port = port;

my_heartbeat_timer.stop();

//socket_connected = false;

tcp_socket->connectToHost(my_ip_address, my_port);
if(tcp_socket->waitForConnected(200))
{
socket_connected = true;

// Disconnect all slots
tcp_socket->disconnect();
disconnect(tcp_socket ,0 ,0 ,0);

emit signal_connected(true);

// re-connect signals and slots.
connect(tcp_socket,SIGNAL(readyRead()),this,SLOT(r ead_data()));
connect(tcp_socket,SIGNAL(disconnected()),this,SLO T(slot_retry_server_connect()));

if (change_state != socket_connected )
{
change_state = socket_connected;
gprintf ("\n> Connected to SocServer %s:%d ",
my_ip_address.toLatin1().data(),
my_port);
}

return true;
}
else
{
socket_connected = false;

if (change_state != socket_connected )
{
// only print error.e message once
change_state = socket_connected;
gprintf ("\n SocServer connect FAILED [%s] Issue reconnect to %s:%d ",
tcp_socket->errorString().toLatin1().data(),
my_ip_address.toLatin1().data(),
my_port);
}

emit signal_connected(false);

disconnect(tcp_socket ,0 ,0 ,0);
tcp_socket->disconnect();
tcp_socket->close();

QTimer::singleShot(5000, this, SLOT(slot_retry_server_connect()));
}
return false;
}
Attached valgrind 'report'

d_stranz
3rd March 2016, 20:23
It is unlikely that it is a real memory leak. It probably results from valgrind not understanding Qt's parent-child lifetime management rules.

The lines inside your destructor:


socket_client::~socket_client(void)
{
if (queue_array != NULL) delete queue_array;
if (tcp_socket != NULL) tcp_socket->deleteLater();
}

should be replaced with:


socket_client::~socket_client(void)
{
delete queue_array;
}

because:

1 - if you have initialized queue_array to NULL in your constructor or have allocated it using operator new(), then there is no need to check for NULL before deleting because operator delete() is perfectly happy to accept a NULL pointer and will do nothing.

2 - You do not need to delete tcp_socket or call deleteLater() on it because you constructed is as a child of socket_client, and it will go out of scope when the socket_client instance goes out of scope.