2016-04-22 7 views
1

内構造を埋めようと、私は構造体を次のようしている。sqlite3の - コールバック

static int callback(void* data, int argc, char** argv, char** colName) { 
    Highscore* highscore = (Highscore*)data; 

    highscore->username = argv[0]; 
    highscore->score = argv[1]; 

    return 0; 
} 

とデータベースのオーケストレーションは、構造体と、ここで使用されている:以下のようにそれを使用して

typedef struct { 
    char *username; 
    char *score; 
} Highscore; 

Highscore* getHighscore() 
{ 
    sqlite3* db_handle; 
    int rc; 
    char* zErrMsg; 
    Highscore* highscore = malloc(sizeof(Highscore)); 
    /* highscore->username = malloc(sizeof(100)); */ 
    /* highscore->score = malloc(sizeof(100)); */ 

    //Datenbankverbindung oeffnen 
    rc = sqlite3_open(DATABASE_FILE, &db_handle); 

    char* sSqlString = sqlite3_mprintf 
    ("select U.Username, H.Punkte from Highscore H join User U on U.B_ID = H.B_ID order by Punkte desc limit 10"); 

    //SQL Statement ausfuehren 
    rc = sqlite3_exec(db_handle, sSqlString, callback, highscore, &zErrMsg); 

    //Datenverbindung schliessen und Speicher leeren 
    sqlite3_free(sSqlString); 
    rc = sqlite3_close(db_handle); 

    return highscore; 

} 

問題は、コールバックスコープ内でHighscore構造体がフィールドを割り当てていることです"username"と "score"はそれがすべきである方法です。私はその位置でデバッグし、すべてうまくいきました。

しかし、 "getHighscore"のスコープに戻ったとき、Highscore構造体のフィールドには任意の値があります。私は何が起こっているのか分かりません?私は "malloc"でコールバックに与える前に、構造体を割り当てました。コールバックの後で同じアドレスかどうかを確認しました。なぜ値が壊れているのですか?

+0

_every_行を取得するために 'callback'が呼び出されます。あなたが正しいことをしたとしても、 'argv'文字列を複製することによって、同じ構造体に対して反復可能な踏み違えを引き起こし、' highscore'は最終行の値しか保持しません。 – Oka

答えて

1

ポインタはHighscore構造体に保持され、実際の値は上書きされます。これを試してみてください:

static int callback(void* data, int argc, char** argv, char** colName) 
{ 
    Highscore* highscore = (Highscore*)data; 

    highscore->username = malloc(strlen(argv[0]) + 1); 
    strcpy(highscore->username, argv[0]); 
    highscore->score = malloc(strlen(argv[1]) + 1); 
    strcpy(highscore->score, argv[1]); 

    return 0; 
} 

freehighscoreを-ing前に)最後にfreescoreusernameに忘れないでください。

+0

ありがとうございました!私はちょうど類似したものを試しましたが、何らかの理由でsizeof(char *)をmallocingしていましたが、 – xetra11

+0

BTWの前に、SQLiteカラムの長さ+ 1のサイズの構造体のchar配列として 'username'と' score'を定義し、 'malloc' /' strlen'/'free'です。 – i486

+0

あなたのメインソリューションはLinux上で正常に動作していましたが、Windows上にSegementation Faultランタイムエラーがあります。 – xetra11

0

sqlite3_exec() documentationは言う:

sqlite3_exec()コールバックに第3引数はsqlite3_column_textからかのようにして得られた文字列へのポインタの配列()、各列に対して1つです。

sqlite3_column_text() documentationは言う:型変換は

と呼ばれる)は、上述のように発生し、又はsqlite3_stepまで()またはsqlite3_reset()またはsqlite3_finalize(まで戻さ

ポインタが有効です

... sqlite3_exec()が返される前に起こります。

自分のバッファに文字列をコピーする必要があります。動的な文字列を持つ言語を使用する方が効果的です。