You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中多次调用mysql_fetch_row不返回NULL(MySQL C API)

问题根源

  • mysql_store_result 返回的结果集是单向遍历的,首次通过mysql_fetch_row遍历完全部行后,结果集游标会停在末尾,后续再调用mysql_fetch_row会直接返回NULL,这是MySQL C API的正常机制。
  • 你之前在循环内直接调用mysql_store_result触发崩溃的原因有两个:
    1. 没有释放上一次申请的MYSQL_RES资源,存在内存泄漏同时会导致连接状态异常
    2. 没有重新执行mysql_query查询语句,连接上没有未读取的新结果集,mysql_store_result直接返回NULL,后续操作空指针就触发了访问冲突报错
  • 你原有代码还存在MYSQL_RES资源未释放的问题,会持续占用内存。

修复方案

这里提供两种可选实现:

方案1:每次校验输入前重新查询数据库(适合角色列表会实时更新的场景)

把查询、结果集获取、结果集释放的逻辑全部放到输入校验循环内部,每次用户输入无效编号时重新拉取最新的角色列表:

void listarPersonagem(MYSQL* conn) {
    int escolha = -1;
    std::map<int, int> indexMap;
    const char* q = "SELECT * FROM personagem";

    while(escolha < 0 || escolha > indexMap.size()) {
        system("cls");
        std::cout << "\t\t\t\t Personagens\n" << std::endl;

        indexMap.clear();
        // 每次循环重新执行查询
        if(mysql_query(conn, q) != 0) {
            // 可自行添加查询失败的报错逻辑
            break;
        }

        MYSQL_RES* res = mysql_store_result(conn);
        if(res == nullptr) {
            break;
        }

        int i = 1;
        MYSQL_ROW row;
        while((row = mysql_fetch_row(res)) != nullptr) {
            std::cout << i << " - " << row[1] << std::endl; 
            indexMap.insert({i, std::atoi(row[0])});
            i++;
        }
        // 用完立即释放结果集资源
        mysql_free_result(res);

        std::cout << "0 - Voltar" << std::endl;
        std::cout << "\n\n=>";
        std::cin >> escolha;
    }

    int id = escolha != 0 ? indexMap[escolha] : 0;
}

方案2:首次查询缓存所有角色数据(性能更高,适合角色列表不会频繁变动的场景)

只查一次数据库,把所有角色信息存到本地容器,后续输入校验直接用本地缓存,不需要反复访问数据库:

void listarPersonagem(MYSQL* conn) {
    std::map<int, std::string> charaList;
    std::map<int, int> indexMap;
    int escolha = -1;

    // 仅执行一次查询,把数据缓存到本地
    if(mysql_query(conn, "SELECT * FROM personagem") == 0) {
        MYSQL_RES* res = mysql_store_result(conn);
        if(res != nullptr) {
            MYSQL_ROW row;
            int i = 1;
            while((row = mysql_fetch_row(res)) != nullptr) {
                charaList.insert({i, row[1]});
                indexMap.insert({i, std::atoi(row[0])});
                i++;
            }
            mysql_free_result(res);
        }
    }

    while(escolha < 0 || escolha > charaList.size()) {
        system("cls");
        std::cout << "\t\t\t\t Personagens\n" << std::endl;
        for(auto& item : charaList) {
            std::cout << item.first << " - " << item.second << std::endl;
        }
        std::cout << "0 - Voltar" << std::endl;
        std::cout << "\n\n=>";
        std::cin >> escolha;
    }

    int id = escolha != 0 ? indexMap[escolha] : 0;
}

内容的提问来源于stack exchange,提问作者Yasushiki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 17:24:07