QIODevice readAll() function
-
hi all,
I am reading data from socket as shown below and the error I am getting is: realloc(): invalid next size:... blah blah ..., obviously it is a memory issue.
void TcpConnection::readyRead() { if(!sender()) return; qDebug() << this << "readyread" << m_socket->bytesAvailable(); QByteArray dat = m_socket->readAll(); }
Few things I noticed:
- The error happens after it reads many times successfully.
- If I comment the code line with the readAll() fucntion, the bytesAvailables keeps adding normally and the app does not crash.
- If I the other end sends data slowly (every 100ms) I do not see this memory issue.
The QT environment is running in a virtual machine with vitrtualbox and bridge network connections with the host.
Thanks for helping.
-
Your image shows exactly what we're telling you - you create and use the QTcpSocket from two different thread what is not allowed.
-
@Jc_Opc
This code should not cause a problem. It is just possible that the " realloc(): invalid next size" comes from a problem elsewhere, which gets noticed here becausereadAll()
will obviously do some memory allocation somewhere.Can you reproduce the problem in a program which does literally nothing but what you show?
You will be probably be asked which version of Qt you are using, OS etc.
-
@JonB, based on your comment I tried a simple socket application and I noticed that it does not have any issues running in the same environment, the other big difference, I forgot to mention in my post, is that this socket is not running in the main thread. From the single thread test I just ran, I noticed that there were always bytes available, in the multithreading code I could see some of them are 0 bytes (the function bytesAvailable() is giving 0 bytes sometimes) . Any clue you may have is more than welcome, for now I will review my code and see if the functions I used are thread safe.
thanks
-
Where do you create the tcp socket? Hopefully in the same thread you're reading from it.
-
This is the way I create threads, TcpConnection wrapper and Socket
- Created pool of threads and threads based on number of SDR TcpConnections.
- Get the first available thread.
- Created a TcpConnection object which is a socket wrapper.
- Move the TcpConnection to that thread.
- Emit Signal that TcpConnection was created and passing the current thread pointer in order to create new socket.
- In the current Thread create the socket and wire signals.
6.1. Wire signals between TcpConnection and socket.
I am testing only one thread for now, besides the main GUI thread, and making sure that I am reading from the sender socket and current thread matches the same address when it was created.
Thank you for your insight.
-
QTcpSocket must be created in the same thread where you read/write from it. From my pov you don't do this but can't say exactly from your description.
-
Hi,
Based on your point number 4, it looks like you are doing the wrong thing. Do not move a socket between threads. Create it in the thread (not its constructor).
-
This is what I get when I run memcheck, please have a look at the image, unfortunately I could not export the results.
I am following the last 2 comments and still working on them, when I was reading how to use sockets in threads, I knew sockets can not be passed between threads, but I will have a look again more carefully.
Sorry for the image I do not know how to export the report from QT. Next time will use it from command line which I do not know yet but will find out.
Thanks a lot.
-
Your image shows exactly what we're telling you - you create and use the QTcpSocket from two different thread what is not allowed.
-
Thanks a lot for your insight, double checking my runnable object Tcpthread which inherits QObject too; apart from the run() function, it has other functions and one of them was createSocket(), because this function was in the same runnable I thought it was part of the pooled thread but checking again with Qthread::currentThread, it was not, and I was passing this socket to the pooled thread which was causing the memory leak issue.
Thanks a lot.
-
@Christian-Ehrlicher I tried to understand the log but I can't figure it out how you arrived to your conclusion. I can see that readAll() is in clone but I do not see it anywhere else. Can you please share how you noticed I was using the socket in 2 threads?
Thanks.
-
As you can see QRingBuffer is created in another thread. Since this is used from your QTcpSocket (first backtrace) the only way is that it was created in the main thread.