在类内部将指针存储到sqlite3数据库会引发segfault

时间:2019-07-05 12:16:15

标签: c++ sqlite class

在我的程序中,我正在使用sqlite3数据库。

为了处理Ctrl-C信号并通过关闭数据库并关闭所有Midi端口(我的程序使用RtMidi)来优雅地终止程序,我需要设置一个存储它们的全局对象。我上了课:

class Config {
private:
    sqlite3 *Database;
    RtMidiIn *MidiIn;
    RtMidiOut *MidiOut;

public:     
    sqlite3 *getDatabase();
    void setDatabase(sqlite3 *mDatabase);

    RtMidiIn *getMidiInStream();
    void setMidiInStream(RtMidiIn *mMidiIn);

    RtMidiOut *getMidiOutStream();
    void setMidiOutStream(RtMidiOut *mMidiOut);

    Config();
    ~Config();
};

构造函数:

Config::Config() {
    //open the midi i/o ports (irrelevant to the problem at hand)
    sqlite3 *mDatabase = this->Database;
    if (sqlite3_open(FILE_DATABASE, &mDatabase)) {
        puts(ERROR_MESSAGE_DATABASE_OPEN_FAIL);
        puts(sqlite3_errmsg(this->Database));
    }
    puts(NOTE_MESSAGE_DATABASE_OPEN);
}

但是,当我尝试在sqlite3_open()上调用它们时,sqlite3_close()mConfig->getDatabase()函数给我带来了段错误。

我尝试将字段设为公开并传递mConfig->Database,但这没有任何改变。如何将数据库存储在Config类中?

--------编辑: 我忘了包括获取/设置数据库功能:

sqlite3 *Config::getDatabase() { return this->Database; }

void Config::setDatabase(sqlite3 *mDatabase) { this->Database = mDatabase; }

1 个答案:

答案 0 :(得分:2)

这肯定是错误的:

sqlite3 *mDatabase = this->Database;
if (sqlite3_open(FILE_DATABASE, &mDatabase)) {

sqlite_open调用修改了本地mDatabase,但是Config::Database保持不变。

建议:

  • 初始化POD类型。在现代C ++中,这和sqlite3 *Database = nullptr;

  • 一样琐碎
  • 考虑将数据库指针(和任何其他托管资源)包装到仅负责管理此资源的助手类中。一种可能的解决方案是使用自定义删除器的shared_ptr