LoginSignup
2
0

More than 5 years have passed since last update.

【sqlite C/C++ API】sqlite3_errmsg()に渡す引数のNULLチェックは不要

Posted at

sqlite3_errmsg()について

関数sqlite3_errmsg()はデータベースハンドラsalite3*を引数にとり、そのデータベースハンドラで直前に発生したエラーに関するメッセージを返す。
例えば、存在しないファイルに対して読み込み専用オプションをつけてsqlite3_open_v2()を呼び出すと、以下のようにエラーが発生する。

    const char *not_exist_file = "notexist.sqlite";
    sqlite3 *db = NULL;
    int rc = sqlite3_open_v2(not_exist_file, &db, SQLITE_OPEN_READONLY, NULL);
    if (rc != SQLITE_OK)
    {
        printf("[%s]\n", sqlite3_errmsg(db));   // [unable to open database file]
    }
    sqlite3_close(db);

エラーが発生していない場合は、以下の例のように、"not an error"を返す。

    sqlite3 *db = NULL;
    int rc = sqlite3_open("filePath.sqlite", &db);
    if (rc == SQLITE_OK)
    {
        printf("[%s]\n", sqlite3_errmsg(db));    // [not an error]
    }
    sqlite3_close(db);

sqlite3_errmsg()NULLを渡してみる

公式リファレンスによると、関数sqlite3_open()およびsqlite3_open_v2()は、DB接続のオープンに失敗した場合も、引数として渡されたデータベースハンドラに非NULLの値を書き込む。ただし、メモリ領域の確保に失敗した場合は、データベースハンドラにNULLが書き込まれる。
そこで、メモリ領域確保に失敗したことを想定して、sqlite3_errmsg()NULLを渡してみる。

int main(int argc, char **argv)
{
    printf("[%s]\n", sqlite3_errmsg(NULL));     // [out of memory]
}

"out of memory"という文字列が返された。
上記のコードでは、実際にはメモリ領域の確保を試行していない。sqlite3_errmsg()NULLが渡される状況とは、メモリ領域の確保に失敗した、すなわちメモリ枯渇状況である、と判断してこのメッセージを返す仕様としているのだろう。

以上を踏まえて

以上の実験から、sqlite3_open()またはsqlite3_open_v2()が返す値がSQLITE_OKでなかった場合のエラーメッセージ取得は、データベースハンドラがNULLか非NULLかにかかわらず、以下のように記述すれば良いことになる。

    sqlite3 *db = NULL;
    const char *errMsg;
    int rc = sqlite3_open("filePath.sqlite", &db);  /* もしくはsqlite3_open_v2関数の呼び出し */
    if (rc != SQLITE_OK)
    {
        errMsg = sqlite3_errmsg(db);
        // errMsgをログや標準エラーなどに出力
        // その他、必要なエラーハンドリング
    }
    sqlite3_close(db);

まとめ

  • sqlite3_open()およびsqlite3_open_v2()はエラー発生時に以下の挙動をする。
    • メモリ領域確保エラーの場合:引数として渡したデータベースハンドラにNULLを書き込む
    • それ以外のエラーの場合:引数として渡したデータベースハンドラに非NULL値を書き込む。
  • sqlite3_errmsg()にはNULLを渡しても安全なので、エラー発生時には引数のNULLチェックを行わずにsqlite3_errmsg()にデータベースハンドラを渡して良い。

参考

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0