1

私の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

コードの問題は何ですか?

4

1 に答える 1

4

セグメンテーション違反の理由

sqlite3ドキュメントにsqlite3_column_textは次のように書かれています:

これらのルーチンのいずれかが呼び出された場合 [...]sqlite3_step()が 以外のものを返した場合SQLITE_ROW、結果は未定義です。」

の戻り値をチェックしていないsqlite3_stepため、クエリが何らかのエラーをsqlite3_column_text返し、無効なポインターを返しているようです。

SQL エラーのデバッグ

のドキュメントにprepareよると:

およびインターフェイスはsqlite3_prepare_v2()sqlite3_prepare16_v2()すべての新しいプログラムに推奨されます。2 つの古いインターフェイス [ を含む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>for#include <string.h>bool CanClose()for を使用しbool CanClose(void)ます。

于 2012-12-22T21:20:18.670 に答える