Code::Blocks执行MySQL循环插入C++程序时返回0xC0000005错误的解决
解决C++ MySQL循环插入时程序崩溃(0xC0000005)的问题
问题描述
我是C++新手,正在开发需持续向数据库插入数据的程序,使用XAMPP搭建数据库,希望在函数内实现插入循环。运行程序时能插入部分数据,但几秒后程序终止,返回错误码-10737741819(0xC0000005),构建日志显示进程终止状态为-1073741510。
原代码:
#include "stdio.h" #include "fstream" #include "iostream" #include "mysql.h" #include "sstream" void loop(); void print(); int i; const char* hostname = "localhost"; const char* username = "root"; const char* password = ""; const char* database = "testinsertdb"; unsigned int port = 3306; const char* unixsocket = NULL; unsigned long clientflag = 0; insertion(){ MYSQL* conn; conn = mysql_init(0); conn = mysql_real_connect(conn, hostname, username, password, database, port, unixsocket, clientflag); int qstate=0; using namespace std; stringstream ss; ss << " INSERT INTO test (number) values ('" <<i<<"')"; string query = ss.str (); const char * q = query.c_str(); qstate = mysql_query(conn, q); if (qstate == 0) { cout <<" Record inserted successfully ..."<<endl; } else { cout <<" Error, data not inserted..."<<endl; } } int main() { print(); return 0; } void print() { for (int j = 0; j < 1000000; j++) { loop(); } } void loop() { i=1; insertion(); }
解决方案
1. 修复核心崩溃问题
程序崩溃(0xC0000005为内存访问违规)的主要原因:
- 每次调用
insertion()新建数据库连接但从不关闭,导致连接资源耗尽、内存泄漏 - 未检查
mysql_real_connect()返回值,连接失败时conn为NULL,调用mysql_query()触发空指针访问
修复代码:复用单个数据库连接,避免重复创建/销毁:
#include "stdio.h" #include "fstream" #include "iostream" #include "mysql.h" #include "sstream" using namespace std; MYSQL* conn; const char* hostname = "localhost"; const char* username = "root"; const char* password = ""; const char* database = "testinsertdb"; unsigned int port = 3306; const char* unixsocket = NULL; unsigned long clientflag = 0; // 初始化数据库连接 bool initDB() { conn = mysql_init(0); if (!conn) { cout << "mysql_init failed: " << mysql_error(conn) << endl; return false; } conn = mysql_real_connect(conn, hostname, username, password, database, port, unixsocket, clientflag); if (!conn) { cout << "mysql_real_connect failed: " << mysql_error(conn) << endl; return false; } cout << "Connected to database successfully!" << endl; return true; } // 关闭数据库连接 void closeDB() { if (conn) { mysql_close(conn); cout << "Database connection closed." << endl; } } // 插入数据,复用已有连接 void insertion(int value) { if (!conn) { cout << "Error: No database connection!" << endl; return; } int qstate = 0; stringstream ss; ss << "INSERT INTO test (number) values ('" << value << "')"; string query = ss.str(); const char* q = query.c_str(); qstate = mysql_query(conn, q); if (qstate != 0) { cout << "Error inserting data: " << mysql_error(conn) << endl; } } int main() { if (!initDB()) { return 1; } // 循环插入100万条自增数据 for (int j = 1; j <= 1000000; j++) { insertion(j); } closeDB(); return 0; }
2. 优化插入效率(推荐)
100万次单条插入效率极低,建议用以下两种方式优化:
方式A:预处理语句
避免重复解析SQL,提升效率同时防止SQL注入:
void batchInsert(int start, int count) { MYSQL_STMT* stmt = mysql_stmt_init(conn); if (!stmt) { cout << "mysql_stmt_init failed: " << mysql_error(conn) << endl; return; } const char* query = "INSERT INTO test (number) VALUES (?)"; if (mysql_stmt_prepare(stmt, query, strlen(query)) != 0) { cout << "mysql_stmt_prepare failed: " << mysql_stmt_error(stmt) << endl; mysql_stmt_close(stmt); return; } MYSQL_BIND bind[1]; memset(bind, 0, sizeof(bind)); int value; bind[0].buffer_type = MYSQL_TYPE_LONG; bind[0].buffer = &value; if (mysql_stmt_bind_param(stmt, bind) != 0) { cout << "mysql_stmt_bind_param failed: " << mysql_stmt_error(stmt) << endl; mysql_stmt_close(stmt); return; } for (int i = start; i < start + count; i++) { value = i; if (mysql_stmt_execute(stmt) != 0) { cout << "Insert failed for " << i << ": " << mysql_stmt_error(stmt) << endl; } } mysql_stmt_close(stmt); } // main函数中调用分批次插入 int main() { if (!initDB()) { return 1; } int batchSize = 1000; for (int j = 1; j <= 1000000; j += batchSize) { batchInsert(j, min(batchSize, 1000000 - j + 1)); cout << "Inserted batch: " << j << " to " << j + batchSize - 1 << endl; } closeDB(); return 0; }
方式B:批量SQL插入
将多条插入合并为单条SQL,减少网络交互:
void batchInsertSQL(int start, int count) { stringstream ss; ss << "INSERT INTO test (number) VALUES "; for (int i = start; i < start + count; i++) { if (i != start) ss << ", "; ss << "(" << i << ")"; } string query = ss.str(); if (mysql_query(conn, query.c_str()) != 0) { cout << "Batch insert failed: " << mysql_error(conn) << endl; } else { cout << "Batch inserted " << count << " records." << endl; } }
3. 修复其他代码问题
- 原代码
insertion()函数无返回类型,C++要求必须显式声明(如void) - 全局变量
i被强制设为1,导致插入数据重复,改为直接传递循环变量更合理 - 循环中频繁打印日志会拖慢程序,建议注释或批量打印
4. 错误码说明
0xC0000005:内存访问违规,通常由空指针访问、内存耗尽导致-1073741510:对应0xC000013A,表示程序被系统强制终止(多因内存占用过高)
内容的提问来源于stack exchange,提问作者anonymous
相关产品推荐
相关产品推荐

