ZBLOG

QHash& hash = ConnectClientInfo::GetSocketHash(); for (auto it = hash.constBegin(); it != hash.constEnd(); ++it) { qDebug()

在你的代码中,遍历 QHash 并在特定条件下删除元素可能会导致问题,因为在迭代过程中修改容器的大小是不可取的。你在循环内对哈希表进行了删除操作,但因为使用了迭代器,可能导致行为未定义或迭代器失效。要正确处理,可以采取以下方法之一:

方法一: 使用临时列表记录待删除的键

在遍历 QHash 的时候,将需要删除的键存储在一个临时容器中,遍历完成后再进行删除。这可以避免直接在原容器上进行修改。

QHash<int, st_Studbanswer*>& hash = ConnectClientInfo::GetSocketHash();
QList<int> keysToRemove; // 用于存储待移除的键

for (auto it = hash.constBegin(); it != hash.constEnd(); ++it) {
    qDebug() << "Key:" << it.key() << ", Value:" << it.value();
    st_Studbanswer* banswerData = it.value();

    if (banswerData->HeartbeatStats == 1) {
        banswerData->HeartbeatStats = 0;
    } else if (banswerData->HeartbeatStats == 0) {
        SOCKET sock = static_cast<SOCKET>(it.key());
        
        qDebug() << "SOCKET sock = (SOCKET)(it.key()); ";

        if (closesocket(sock) == SOCKET_ERROR) {
            qDebug() << "closesocket failed: " << WSAGetLastError() << endl;
        } else {
            qDebug() << "delete hash.value(it.key());";
            delete banswerData; // 释放动态内存
            keysToRemove.append(it.key()); // 将键添加到待删除列表
        }
    }
}

// 从 QHash 中移除所有标记为待删的项
for (int key : keysToRemove) {
    hash.remove(key);
}

方法二: 倒序遍历

如果你不想使用临时列表,可以考虑倒序遍历。如果使用整数作为 QHash 的键(如 int 类型),则可以将其转换成 QList 或 QVector 来实现反向遍历。

方法三: 使用 QMutableHashIterator

另一种选择是使用 QMutableHashIterator,这个迭代器允许你在循环过程中安全地删除项。

QHash<int, st_Studbanswer*>& hash = ConnectClientInfo::GetSocketHash();
QMutableHashIterator<int, st_Studbanswer*> it(hash);

while (it.hasNext()) {
    it.next();
    qDebug() << "Key:" << it.key() << ", Value:" << it.value();
    
    st_Studbanswer* banswerData = it.value();
    
    if (banswerData->HeartbeatStats == 1) {
        banswerData->HeartbeatStats = 0;
    } else if (banswerData->HeartbeatStats == 0) {
        SOCKET sock = static_cast<SOCKET>(it.key());

        qDebug() << "SOCKET sock = (SOCKET)(it.key()); ";
        
        if (closesocket(sock) == SOCKET_ERROR) {
            qDebug() << "closesocket failed: " << WSAGetLastError() << endl;
        } else {
            qDebug() << "delete hash.value(it.key());";
            delete banswerData; // 删除指针指向的数据
            it.remove(); // 安全地从 QHash 中移除当前项
        }
    }
}

以上方法都可以避免因直接修改容器而引起的问题,你可以根据自己的需求选择适合的方法来处理。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=19776

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?