QTcpSocket::waitForReadyRead continually reserved lots of memory
-
I have a desktop application, which receving lots of data from TCP connection, the memory leak is found. I minimized it to a quite simple program it is still the same, i can't understand what happend. I used Visutal studio 2022 to debug it when the tcp is connected, the TCP server will send data to my desktop, I use visutal studio "diagnostic Tools && Heap profiing", take two snapshots, and diff it found lots of memory is reserved by the waitForReadyRead , the call stack look like below:
The main code is like below, it is just started the thread, and starting read the tcpsocket. The wired thing is if i commentd all the code related
ostringstream
, the memeory leak disappears(the two heap snapshot are the same, and proces memory keeps stable). As i understand theoss
var will destructed every time, i can't understand why it can cause 'waitForReadyRead' function reserve many memoryQt Vesion is Qt 6.8.1
void XCPWorkerThread::run() { TestXCP(); } static size_t readBytes(QAbstractSocket* socket, char* data, qint64 n) { char* ptr = data; qint64 nleft = n; while (nleft > 0) { qint64 nread = socket->read(ptr, nleft); if (nread == -1) { qDebug() << "socket closed"; break; } else if (nread == 0) { socket->waitForReadyRead(-1); } nleft -= nread; ptr += nread; } return n - nleft; } static bool readMessage(QAbstractSocket* socket, std::vector<uint8_t>& buffer) { uint16_t packageLength = 0; // if i comment out this variable and related code use it, the memory leak disapper std::ostringstream oss; if (readBytes(socket, (char*)&packageLength, sizeof(packageLength)) != sizeof(packageLength)) { qDebug() << "can't get the xcp message length"; return false; } oss << "Message received, length: " << packageLength; uint16_t messageCounter = 0; if (readBytes(socket, (char*)&messageCounter, sizeof(messageCounter)) != sizeof(messageCounter)) { qDebug() << "can't get the message counter"; return false; } oss << ", counter: " << (int)messageCounter; buffer.resize(packageLength + 4); memcpy((char*)&buffer[0], &packageLength, sizeof(packageLength)); memcpy((char*)&buffer[2], &messageCounter, sizeof(messageCounter)); if (readBytes(socket, (char*)&buffer[4], packageLength) != packageLength) { // qDebug() << "can't get the xcp package"; return false; } oss << ", packet: ["; for (int i = 0; i < packageLength + 4; i++) { oss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (int)(buffer[i]) << " "; } oss << "]"; // qDebug() << oss.str().c_str(); return true; } void XCPWorkerThread::TestXCP() { qDebug() << __FUNCTION__; s = new QTcpSocket(0); s->connectToHost("127.0.0.1", 17725); s->waitForConnected(-1); int i = 0; while (true) { if (s->waitForReadyRead(-1)) { std::vector<uint8_t> buffer(0xFF); if (!readMessage(s, buffer)) { qDebug() << "can't read message from socket"; return; } qDebug() << "readed a pckage" << i++; } } delete s; }
-
Use signals and slots instead a blocking call. Then you also don't need a separate thread.