sqlite3_step (21: out of memory) rs的一种错误原因。

本文分析了在使用FMDB进行数据库操作时遇到的内存溢出错误。具体表现为使用错误的查询结果集变量导致的循环查询问题。当首次查询结束后,再次尝试使用已遍历完的查询结果进行循环时引发错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在使用FMDB时报了sqlite3_step (21: out of memory) rs这样一个错误。

    if ([_DB open]) {
        NSString *sql=[NSString stringWithFormat:@"SELECT * FROM %@",tablename];
        FMResultSet *resultSet=[_DB executeQuery:sql];
        else if ([tablename isEqualToString:@"WXZ"]){
            if (_WXZModelContents.count==0) {
                FMResultSet *resultSet2=[_DB executeQuery:sql];
                while ([resultSet next]) {<span style="color:#ff0000;">//错误出现在这里,错误的将resultSet2写作了resultSet</span>
                    }
                }
                [resultSet2 close];
            }
            while ([resultSet next]) {
                                }
            }
            [resultSet close];
        }

所以这个错误就是出现在多个查询时,使用错误导致。因为在第一次循环查询完毕后,列表已经被查完了,再执行[resultSet next]操作就会报这个错误,类似于数组溢出一样。


<think>在代码片段中,有两个位置出现了乱码“极狐”,需要修正:1.`sqlite3_final极狐`应该是 `sqlite3_finalize`2.`floatprice_out= sqlite3_column_double(stmt极狐`应该是`floatprice_out= sqlite3_column_double(stmt,1);`并且下一行是`intpharmacy_qty =sqlite3_column_int(stmt,2);`修正后的代码片段如下:</think>在代码片段中,`极狐`处应该是以下内容: ```c if (sqlite3_step(stmt) != SQLITE_ROW) { sqlite3_finalize(stmt); // 修正1 ShowMessageBox(L"错误", L"药品不存在"); return; } strcpy_s(sr.med_name, (const char*)sqlite3_column_text(stmt, 0)); float price_out = sqlite3_column_double(stmt, 1); // 修正2 int pharmacy_qty = sqlite3_column_int(stmt, 2); // 修正3 sqlite3_finalize(stmt); // 修正4 ``` ### 完整修正后的代码: ```c if (sqlite3_step(stmt) != SQLITE_ROW) { sqlite3_finalize(stmt); ShowMessageBox(L"错误", L"药品不存在"); return; } strcpy_s(sr.med_name, (const char*)sqlite3_column_text(stmt, 0)); float price_out = sqlite3_column_double(stmt, 1); int pharmacy_qty = sqlite3_column_int(stmt, 2); sqlite3_finalize(stmt); ``` ### 修正说明: 1. **修正1:`sqlite3_finalize(stmt)`** - 正确释放SQLite语句对象 - 避免内存泄漏 - 必须在不再使用语句对象时调用 2. **修正2:`float price_out = sqlite3_column_double(stmt, 1)`** - 从查询结果的第1列(索引1)获取药品售价 - 使用`sqlite3_column_double`获取浮点数值 - 对应SQL查询中的`price_out`列 3. **修正3:`int pharmacy_qty = sqlite3_column_int(stmt, 2)`** - 从查询结果的第2列(索引2)获取药房库存数量 - 使用`sqlite3_column_int`获取整数值 - 对应SQL查询中的`pharmacy_qty`列 4. **修正4:`sqlite3_finalize(stmt)`** - 在成功获取数据后再次释放语句对象 - 确保所有执行路径都有资源释放 ### 完整函数上下文(来自`PharmacySale`函数): ```c void PharmacySale(int employee_id) { SalesRecord sr; sr.id = time(NULL); // 使用时间作为唯一ID sr.med_id = Num_input(L"输入药品编号:"); // 检查药品是否存在 char sql[256]; sprintf_s(sql, "SELECT name, price_out, pharmacy_qty FROM medicines WHERE id = %d;", sr.med_id); sqlite3_stmt* stmt; if (sqlite3_prepare_v2(db, sql, -1, &stmt, 0) != SQLITE_OK) { ShowSQLError(L"数据库错误"); return; } // 修正后的代码段 if (sqlite3_step(stmt) != SQLITE_ROW) { sqlite3_finalize(stmt); ShowMessageBox(L"错误", L"药品不存在"); return; } strcpy_s(sr.med_name, (const char*)sqlite3_column_text(stmt, 0)); float price_out = sqlite3_column_double(stmt, 1); int pharmacy_qty = sqlite3_column_int(stmt, 2); sqlite3_finalize(stmt); // 后续销售逻辑... } ``` ### 关键点: 1. **SQLite API 使用规范**: - `sqlite3_prepare_v2` 准备SQL语句 - `sqlite3_step` 执行语句并获取结果 - `sqlite3_column_*` 系列函数获取列数据 - `sqlite3_finalize` 释放语句资源 2. **错误处理**: - 检查SQLite操作的返回值 - 提供有意义的错误信息 - 确保所有路径都有资源清理 3. **数据获取**: - 列索引从0开始(0=name, 1=price_out, 2=pharmacy_qty) - 使用正确的数据类型获取函数 这个修正确保了药品销售功能能正确检查药品是否存在,并获取必要的药品信息(名称、售价、库存量)以完成销售流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值