Ошибка сегментации в SQLite
Код в моем файле DataBase.cpp:
#include "DataBase.h"
#include <sqlite3.h>
#include <string.h>
#include <wx/msgdlg.h>
bool CanClose(void)
{
sqlite3 *Sqlite;
sqlite3_stmt *sqlstmt;
char *result;
if(sqlite3_open("SysConfig",&Sqlite)==SQLITE_OK)
{
sqlite3_prepare(Sqlite,"SELECT config_value FROM configuration WHERE config_id = 1;",-1,&sqlstmt,NULL);
sqlite3_step(sqlstmt);
result = (char*)sqlite3_column_text(sqlstmt,0);
sqlite3_close(Sqlite);
if(strcmp(result,"YES")==1) //Error Here
return true;
else
return false;
}
else
{
wxMessageBox(_("Cannot Find System File!"),_("Error!"));
sqlite3_close(Sqlite);
return false;
}
}
Моя программа работала неожиданно. Когда я попытался отладить ее, строка, указанная выше (строка 19), выдает ошибку:
программа получила сигнал SIGSEGV, ошибка сегментации.
дальнейшая разборка оператора показывает ошибку при сборке инструкции
call 0x80500b0
Есть идеи, в чем проблема с кодом?
1 ответ
Причина сегфо
Документация sqlite3 дляsqlite3_column_text
говорит:
Если любая из этих подпрограмм называется [...] после
sqlite3_step()
вернул что-то кромеSQLITE_ROW
, результаты не определены."
Вы не проверяете возвращаемое значение sqlite3_step
так что, похоже, ваш запрос возвращает какую-то ошибку, а затем sqlite3_column_text
возвращает неверный указатель.
Отладка ошибки SQL
Согласно документации дляprepare
:
sqlite3_prepare_v2()
а такжеsqlite3_prepare16_v2()
интерфейсы рекомендуются для всех новых программ. Два старых интерфейса [в том числеsqlite3_prepare
, который вы называете] сохраняются для обратной совместимости, но их использование не рекомендуется.[...]
При возникновении ошибки sqlite3_step() возвращает один из подробных кодов ошибок или расширенных кодов ошибок. Устаревшее поведение заключалось в том, что sqlite3_step() будет возвращать только общий код результата SQLITE_ERROR, и приложение должно будет выполнить второй вызов sqlite3_reset(), чтобы найти причину проблемы. С интерфейсами подготовки "v2" основная причина ошибки возвращается немедленно.
Так что если вы переключитесь на более новый интерфейс, он должен дать более информативное сообщение, а не общий SQLITE_ERROR
,
Вы также можете попробовать использовать sqlite3
программа командной строки, которая напрямую сообщит вам, в чем заключается ошибка. Пример сеанса:
user@host:/path$ sqlite3 test.sqlite
sqlite> create table example ( id numeric primary key );
sqlite> select bogus from example;
Error: no such column: bogus
Кстати, для стандартного использования C++ #include <cstring>
за #include <string.h>
а также bool CanClose()
за bool CanClose(void)
,