在 MySQL C API 中,关闭 `mysql_store_result` 申请的结果集使用:
正确的释放函数:
```c
mysql_free_result(MYSQL_RES *result);
```
在你的代码中的使用:
```cpp
// 申请结果集
MYSQL_RES* res = mysql_store_result(sql);
// 使用结果集...
// 释放结果集
mysql_free_result(res);
res = nullptr; // 可选:设置为nullptr避免野指针
```
完整的正确代码示例:
```cpp
#include <iostream>
#include <string>
#include <cstring>
#include <mysql/mysql.h>
const std::string host = "localhost";
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
unsigned int port = 3306;
int main(){
MYSQL * sql = mysql_init(nullptr);
if(sql == nullptr)
{
std::cerr << "mysql初始化失败" << std::endl;
return 1;
}
mysql_set_character_set(sql, "utf8");
if(!mysql_real_connect(sql, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0))
{
std::cerr << "mysql连接失败" << std::endl;
return 2;
}
std::string onemysql;
MYSQL_RES* res = nullptr; // 初始化为nullptr
while(true)
{
std::cout << "MySQL<<<";
if(!std::getline(std::cin, onemysql) || onemysql == "quit")
{
break;
}
int ret = mysql_query(sql, onemysql.c_str());
if(ret == 0)
{
std::cout << onemysql << " success: " << ret << std::endl;
// 获取结果集
res = mysql_store_result(sql);
if(res != nullptr)
{
// 处理结果集...
uint64_t row_count = mysql_num_rows(res);
uint64_t field_count = mysql_num_fields(res);
// 提取字段信息
MYSQL_FIELD* fields = mysql_fetch_fields(res);
for(uint64_t i = 0; i < field_count; i++)
{
std::cout << fields[i].name << "\t";
}
std::cout << std::endl;
// 提取行数据
MYSQL_ROW row;
while((row = mysql_fetch_row(res)))
{
for(uint64_t j = 0; j < field_count; j++)
{
std::cout << (row[j] ? row[j] : "NULL") << "\t";
}
std::cout << std::endl;
}
// ✅ 正确释放结果集
mysql_free_result(res);
res = nullptr; // 避免野指针
}
else
{
// 对于非SELECT查询,mysql_store_result返回nullptr是正常的
if(mysql_field_count(sql) == 0)
{
std::cout << "影响的行数: " << mysql_affected_rows(sql) << std::endl;
}
else
{
std::cerr << "mysql_store_result error: " << mysql_error(sql) << std::endl;
}
}
}
else
{
std::cout << onemysql << " failed: " << mysql_error(sql) << std::endl;
}
}
// 最后清理
if(res != nullptr)
{
mysql_free_result(res); // 确保释放
}
mysql_close(sql);
return 0;
}
```
重要注意事项:
-
**每次调用 `mysql_store_result` 后都必须调用 `mysql_free_result`**
-
**在循环中要及时释放**,避免内存泄漏
-
**设置为 `nullptr`** 可以避免重复释放
-
**对于非SELECT语句**,`mysql_store_result` 返回 `nullptr` 是正常的
内存管理对比:
| 函数 | 用途 | 需要释放 |
|------|------|----------|
| `mysql_store_result()` | 获取整个结果集 | 是,用 `mysql_free_result()` |
| `mysql_use_result()` | 逐行获取结果集 | 是,用 `mysql_free_result()` |
| `mysql_fetch_row()` | 获取一行数据 | 自动管理 |
| `mysql_fetch_fields()` | 获取字段信息 | 自动管理 |
记住:**有 `mysql_store_result` 就必须有对应的 `mysql_free_result`**!