Хранение указателя на базу данных sqlite3 внутри класса генерирует segfault - PullRequest
2 голосов
/ 05 июля 2019

В моей программе я использую базу данных 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?

-------- РЕДАКТИРОВАТЬ: Я забыл включить функции базы данных get / set:

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

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

1 Ответ

2 голосов
/ 05 июля 2019

Это, безусловно, ошибочно:

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

вызов sqlite_open изменяет локальный mDatabase, но Config::Database остается неизменным.

Рекомендации:

  • инициализировать типы POD. в современном C ++ это так же тривиально, как sqlite3 *Database = nullptr;

  • рассмотрите возможность упаковки указателя базы данных (и любого другого управляемого ресурса) в вспомогательный класс, отвечающий только за управление этим ресурсом. Одним из возможных решений будет shared_ptr с пользовательским средством удаления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...