码迷,mamicode.com
首页 > 其他好文 > 详细

关于QSocket的释放的一个需要注意的情况

时间:2015-08-25 16:47:42      阅读:121      评论:0      收藏:0      [点我收藏+]

标签:

最近在用QtNetwork编写服务器程序进行TCP/IP通信,大体过程如下:

1. 创建一个QTcpServer实例,监听目标IP和端口;

2. 一旦监听到有连接,获取和客户端之间的socket;

3. 使用socket进行通信;

4. 通信结束后,可以手动释放socket,也可以不管它,在释放QTcpServer的时候会把其下的所有socket全部自动释放。


在编写时,我做了如下事:

TcpNetwork::TcpNetwork()
{
    ...
    connect(mySocket, SIGNAL(disconnect(QTcpSocket*)), this, SLOT(ServerConnectionLost(QTcpSocket*)));
    ...
}

TcpNetwork::~TcpNetwork()
{
    if (tcpServer != NULL)
    {
        delete tcpServer;
    }
}
<pre name="code" class="cpp">void TcpNetwork::ServerConnectionLost(QTcpSocket *socket)
{   
    if (socket == mySocket)
    {
        ...
        // debug
        delete mySocket;
        mySocket = NULL;
        ...
    }
}




这样在关闭程序窗口时会导致崩溃,看了一下QTcpServer的析构函数源码后发现,在析构时Qt会首先检查QtcpServer下的socket指针所指向内存是否已被释放,然后执行每个socket的关闭操作,随后释放刚才被检查过的未被释放的socket内存,最后释放QTcpServer。


如果将QTcpSocket::disconnect()信号与一个其中带有释放socket操作的槽连接起来,那么如果socket还没有关闭就直接析构QTcpServer,在执行断开socket这一步时(如果之前已经断开了就不会再执行这一步了)会触发带有删除socket操作的槽,然而析构函数对此一无所知,紧接着便是析构函数来释放socket,也就造成了socket的内存的重复释放,导致崩溃。


解决方法:在关闭窗口之前先关闭socket,这样在析构函数中就不会再执行关闭socket的操作。或者不在连接断开时添加含有释放socket操作的槽。

版权声明:本文为博主原创文章,未经博主允许不得转载。

关于QSocket的释放的一个需要注意的情况

标签:

原文地址:http://blog.csdn.net/qq_19672579/article/details/47973409

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!