让堆栈损坏调用mysql_close,这是MySQL中的错误吗?

时间:2015-05-17 16:17:11

标签: c++ mysql stack-corruption

我在Boost测试框架中调用此代码来检查堆栈损坏。

我收到此错误消息: 运行时检查失败#2 - 变量'temp'周围的堆栈已损坏。如果我成功打开了与mysql数据库的连接并不重要。如果我注释掉mysql_close调用,我就不会收到这样的消息。

我安装了MySQL Server 5.6,并且我正在链接到这些目录:

C:\Program Files\MySQL\MySQL Connector.C 6.1\lib
C:\Program Files\MySQL\Connector.C++ 1.1\lib\opt

我正在运行我在这里找到的DLL:

C:\Program Files\MySQL\MySQL Connector.C 6.1\lib\libmysql.dll

我想知道调用约定是否错误,因为这是一个c ++项目?解决这个问题的正确方法是什么?其他一切似乎都正常工作,我没有从任何其他mysql_调用中获得堆栈损坏。

我的函数定义为:

void create_db(const std::string &host, const std::string &username, const std::string &password, const std::string &name)
{
    MYSQL temp;
    mysql_init(&temp);
    if (!mysql_real_connect(&temp, host.c_str(), username.c_str(), password.c_str(), NULL, 0, NULL, 0))
    {
        throw mysql_db::error(mysql_error(&temp), DETAILS, mysql_errno(&temp));
    }
    std::string query_str("CREATE DATABASE IF NOT EXISTS "+name);
    if (0 != mysql_real_query(&temp, query_str.c_str(), (unsigned long)query_str.length())) {
        mysql_close(&temp);
        throw database::error(mysql_error(&temp), DETAILS, mysql_errno(&temp));
    }
    mysql_close(&temp);
}

我可以注释掉所有内容以重现这个问题,只留下:

void create_db(const std::string &host, const std::string &username, const std::string &password, const std::string &name)
    {
        MYSQL temp;
        mysql_init(&temp);
        mysql_close(&temp);
    }

mysql_close的MySQL文档内容如下:

  

20.6.7.5 mysql_close()   void mysql_close(MYSQL * mysql)

描述

关闭先前打开的连接。如果句柄是由mysql_init()或mysql_connect()自动分配的话,mysql_close()也会解除分配mysql指向的连接句柄。

所以我认为我可以在这里调用mysql_close。

1 个答案:

答案 0 :(得分:1)

MySQL库期望MYSQL指针是malloc()在堆上分配的对象; mysql_close()函数最终将尝试free()指针结尾。对于堆栈中的对象,这不能正常工作。

您需要使用malloc()自行分配此对象,或允许mysql_init()自行分配此对象,例如。

MYSQL *temp = mysql_init(NULL);
...
mysql_free(temp);

MYSQL *temp = malloc(sizeof(MYSQL));
mysql_init(temp);
...
mysql_free(temp);