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

sqlite3_column_text返回unsigned char*乱码导致比对失败如何解决

问题产生原因
  • 核心原因1:sqlite3_column_text()返回的指针生命周期和预处理语句对象stmt完全绑定,你在读取返回值后直接调用了sqlite3_finalize(stmt)销毁了stmt,此时result指针指向的内存已经被SQLite释放,后续访问属于野指针访问,自然会出现乱码、无效值。
  • 核心原因2:你用==比较两个unsigned char*类型的变量,本质是比较两个指针指向的内存地址,而不是指针指向的字符串内容。就算两个指针指向的字符串完全相同,只要存储地址不同,比较结果永远是false。
  • 额外隐藏问题:你没有判断sqlite3_step()的返回值是否为SQLITE_ROW,如果查询没有命中任何行,sqlite3_column_text()会直接返回NULL,也会导致后续访问异常;另外你直接拼接SQL语句存在SQL注入风险,且函数声明为void返回类型却写了return -1属于语法错误,输出语句还漏写了引号闭合符。
修复方案

你只需要在销毁stmt之前把查询到的字符串拷贝到自己管理的内存中,再用标准字符串比较方法比对即可,修改后的参考代码如下:

// 函数返回值改成bool更合理,用来返回是否匹配
bool check_username(std::string username)
{
    sqlite3_stmt* stmt;
    // 不要直接拼接SQL,用参数绑定避免注入,先写带占位符的SQL
    const char* query = "SELECT username FROM bank_account WHERE username = ?;";
   
    int rc = sqlite3_prepare_v2(DB, query, -1, &stmt, NULL);
    if (rc != SQLITE_OK) 
    {
        std::cerr << "Error: " << sqlite3_errmsg(DB) << std::endl;
        sqlite3_finalize(stmt);
        return false;
    }
    // 绑定参数,第1个参数下标是1,绑定字符串内容
    sqlite3_bind_text(stmt, 1, username.c_str(), -1, SQLITE_STATIC);

    rc = sqlite3_step(stmt);
    bool is_match = false;
    // 先判断是否查询到了结果行
    if (rc == SQLITE_ROW) {
        // 在销毁stmt前直接把结果转成std::string,拷贝内容到自己的变量里
        const char* result = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
        std::string result_str(result);
        // 直接用std::string的==比较内容即可
        is_match = (result_str == username);
    }
    // 用完再销毁stmt
    sqlite3_finalize(stmt);
    
    if (is_match)
        std::cout << "It's match!" << std::endl;
    else
        std::cout << "It's not match!" << std::endl;
    return is_match;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 17:48:02