【发布时间】:2014-03-18 13:19:56
【问题描述】:
我需要关于 QTcpSocket 不断增长的记忆的帮助。
当然我发现了类似的问题here、here 和here,但不幸的是他们并没有为我解决这个问题。
我写了一个简单的类,封装了QTcpSocket:
#include "GWCommunicator.h"
GWCommunicator::GWCommunicator() {
socket = new QTcpSocket(this);
}
bool GWCommunicator::send(const char *data, qint64 size) {
socket->write(data, size);
return socket->waitForBytesWritten();
}
GWCommunicator::~GWCommunicator() {
delete socket;
}
bool GWCommunicator::connectToServer() {
socket->connectToHost(SERVERIP, 6498, QIODevice::ReadWrite);
return socket->waitForConnected();
}
bool GWCommunicator::disconnectFromServer() {
socket->disconnectFromHost();
return socket->waitForDisconnected();
}
其中socket 是QTcpSocket*,在头文件中声明为私有字段。
在功能方面,一切都很好。但是这个套接字随着每条消息的发送消耗越来越多的内存。这不是实际的泄漏,而是某种缓冲(与 QIODevice 文档相对应 - QTcpSocket 的注释)。文档还说您可以在打开设备时使用无缓冲模式。但这在 QTcpSocket 中是不可能的:
注意:不能在 QIODevice::Unbuffered 模式下打开 TCP 套接字。
我应该如何避免它?我知道waitForBytesWritten() 应该这样做,但显然没有。
主类如下所示:
#include "GWCommunicator.h"
#include <iostream>
using namespace std;
GWCommunicator *communicator;
int main(/*int argc, char *argv[]*/) {
communicator = new GWCommunicator();
communicator->connectToServer();
string stdstr("Hello world");
const char* str = stdstr.c_str();
int count = 0;
int length = stdstr.size();
while (count++ < 10000) {
communicator->send(str, length);
}
communicator->disconnectFromServer();
delete communicator;
return 0;
}
我的头文件如下。
#include <QObject>
#include <QTcpSocket>
#ifndef GWCOMMUNICATOR_H
#define GWCOMMUNICATOR_H
#define SERVERIP "127.0.0.1"
class GWCommunicator : private QObject {
Q_OBJECT
public:
GWCommunicator();
~GWCommunicator();
bool connectToServer();
bool disconnectFromServer();
bool send(const char *datam, qint64 size);
private:
QTcpSocket *socket;
};
#endif /* GWCOMMUNICATOR_H */
【问题讨论】:
-
您确定内存泄漏是由
QTcpSocket引起的,而不是由您的代码引起的吗?例如,您可能忘记释放您传递给GWCommunicator::send()的const char *data,或类似的东西。要检查QTcpSocket是否泄漏,请尝试创建一个仅写入套接字的测试程序,然后启动它并读取其输出,看看它是否增加了内存。如果是,请将该测试程序作为 SSCCE 发布。我还注意到您的用户配置文件中的 Java 标记,如果您主要是 Java 程序员,很可能您忘记了释放某些东西。 -
如果您将父级传递给套接字的构造函数,则不需要
delete它,因为您有双重删除 -
@Kousalik 不过,您是否创建了 SSCCE 并对其进行了测试?如果有,请发布。
-
@Kousalik 啊,那么没有错误,只是错误的错觉。数据确实被缓冲了,但是一旦从套接字中读取它就会从缓冲区中删除。如果您只是“发送”连接另一端从未读取的数据,它当然会累积,等待。如果实际正在读取数据,您能否重现泄漏?试试
netcat这是一个免费工具。 -
你怎么知道你有内存泄漏?你用的是什么工具?你怎么知道每次通过套接字发送东西时内存消耗都会增加?服务器响应怎么样 - 我在您的代码中看不到任何读数?
标签: c++ qt memory-leaks qtcpsocket