C语言连接MySQL,在一个mian函数里没事,放到单独的函数里就运行时出错。

我写一个连接mysql数据库的程序.编程环境,linux2.6.38,g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3,mysql 5.1.41-3ubuntu12.10 (Ubuntu)。把所有连接步骤都放到main函数里的时侯没问题,但是如果把连接过程放到一个单独的函数里在编译执行,编译没有报错,运行时出错,如下:
C/C++ code

#include <iostream>
#include <cstdlib>
#include <mysql/mysql.h>
#include <string>

using namespace std;

//初始化mysql数据库
bool InitDatabase(MYSQL * connect)
{
    connect = NULL;
    string server = "localhost";
    string user;
    string password;
    string database = "libmanager";
    cout<<"输入用户名:";
    cin>>user;
    cout<<"输入密码:";
    cin>>password;
    connect = mysql_init(NULL);
    if (connect == NULL)
    {
        cout<<"初始化连接失败"<<mysql_error(connect)<<endl;
        return false;
    }
    if (!mysql_real_connect(connect, server.c_str(),
                user.c_str(), password.c_str(),
                database.c_str(), 0, NULL, 0))
    {
        cout<<"连接MySQL数据库失败,失败代码:"<<mysql_error(connect)<<endl;
        return false;
    }

    return true;
}

//断开数据库连接
void DisconnectDatabase(MYSQL * connect)
{
    if (connect != NULL)
    {
        mysql_close(connect);
    }
}

int main()
{
    MYSQL * connect;
    /*
    connect = NULL;
    string server = "localhost";
    string user;
    string password;
    string database = "libmanager";
    cout<<"输入用户名:";
    cin>>user;
    cout<<"输入密码:";
    cin>>password;
    connect = mysql_init(NULL);
    if (connect == NULL)
    {
        cout<<"初始化连接失败"<<mysql_error(connect)<<endl;
        return false;
    }
    if (!mysql_real_connect(connect, server.c_str(),
                user.c_str(), password.c_str(),
                database.c_str(), 0, NULL, 0))
    {
        cout<<"连接MySQL数据库失败,失败代码:"<<mysql_error(connect)<<endl;
        return false;
    }*/

    if (!InitDatabase(connect))
    {
        cout<<"连接数据库失败:"<<mysql_error(connect)<<endl;
        exit(1);
    }
    else
    {
        cout<<"数据库连接成功"<<endl;
    }
    cout<<mysql_error(connect)<<endl;
    
    DisconnectDatabase(connect);
    return 0;
}



直接运行显示:
输入用户名:zym
输入密码:
数据库连接成功


命令已结束

请按 ENTER 或其它命令继续
用gdb调试
gdb ./test


GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/zym/code/libmanager/src/test...done.
(gdb) run
Starting program: /home/zym/code/libmanager/src/test 
[Thread debugging using libthread_db enabled]
输入用户名:zym
输入密码:
数据库连接成功


Program received signal SIGSEGV, Segmentation fault.
0xb7e1101d in free_root () from /usr/lib/libmysqlclient.so.16
出现段错误,gdb单步跟踪到mysql_close(connect);时出错。
如果把程序里main程序的注释那段取消注释,再把调用我写的函数那段注释掉,如下:
C/C++ code

#include <iostream>
#include <cstdlib>
#include <mysql/mysql.h>
#include <string>

using namespace std;

//初始化mysql数据库
bool InitDatabase(MYSQL * connect)
{
    connect = NULL;
    string server = "localhost";
    string user;
    string password;
    string database = "libmanager";
    cout<<"输入用户名:";
    cin>>user;
    cout<<"输入密码:";
    cin>>password;
    connect = mysql_init(NULL);
    if (connect == NULL)
    {
        cout<<"初始化连接失败"<<mysql_error(connect)<<endl;
        return false;
    }
    if (!mysql_real_connect(connect, server.c_str(),
                user.c_str(), password.c_str(),
                database.c_str(), 0, NULL, 0))
    {
        cout<<"连接MySQL数据库失败,失败代码:"<<mysql_error(connect)<<endl;
        return false;
    }

    return true;
}

//断开数据库连接
void DisconnectDatabase(MYSQL * connect)
{
    if (connect != NULL)
    {
        mysql_close(connect);
    }
}

int main()
{
    MYSQL * connect;
    connect = NULL;
    string server = "localhost";
    string user;
    string password;
    string database = "libmanager";
    cout<<"输入用户名:";
    cin>>user;
    cout<<"输入密码:";
    cin>>password;
    connect = mysql_init(NULL);
    if (connect == NULL)
    {
        cout<<"初始化连接失败"<<mysql_error(connect)<<endl;
        return false;
    }
    if (!mysql_real_connect(connect, server.c_str(),
                user.c_str(), password.c_str(),
                database.c_str(), 0, NULL, 0))
    {
        cout<<"连接MySQL数据库失败,失败代码:"<<mysql_error(connect)<<endl;
        return false;
    }

    /*
    if (!InitDatabase(connect))
    {
        cout<<"连接数据库失败:"<<mysql_error(connect)<<endl;
        exit(1);
    }
    else
    {
        cout<<"数据库连接成功"<<endl;
    }
    */
    cout<<mysql_error(connect)<<endl;
    
    DisconnectDatabase(connect);
    return 0;
}



输入用户名:zym
输入密码:


请按 ENTER 或其它命令继续
这样就没有错误了。
用户名,密码都是对的,数据库也是存在的,在shell里登录进入数据库正常。
我估计是connect指针的缘故,但是到底是哪里出错了,我实在是看不出来,求助大家了。谢谢了!

作者: zwdnet   发布时间: 2011-06-02

楼主用C++语言写的C程序?

不管怎么样,
bool InitDatabase(MYSQL * connect);
它们都不能改变connect指针,
所以到了下边这个函数调用的时候,connect的值还是初始的connect值。
DisconnectDatabase(MYSQL * connect);

解决的办法是:
1. 对MYSQL*用全局变量,即两个函数都不带参数
或者
2. 使用双重指针MYSQL** connect

当然,使用面向对象封装是比较好的方法。可惜你用C++写C程序。

作者: iihero   发布时间: 2011-06-03