2012-01-10 132 views
5

我不確定這裏發生了什麼,但是我發現sqlite3_column_text中的返回數據在finalize/close sqlite階段被更改。sqlite3_column_text返回的數據在敲定/關閉期間被破壞

// rc not handled in this abbreviated code 

    sqlite3 *db; 
    sqlite3_stmt *stmt; 
    char * sql; 

    const char * tail; 
    int rc; 

    char * dbName = "C:\\db\\myblobs.db"; 
    int myIndex = 0; 

    char * myLocation1; 
    string myLocation2; 

    rc = sqlite3_open(dbName, &db); 

    sql = "SELECT location FROM blobs WHERE key = ?"; 
    rc = sqlite3_prepare(db, sql, strlen(sql), &stmt, &tail); 
    sqlite3_bind_int(stmt, 1, myIndex); 
    rc = sqlite3_step(stmt); 

    myLocation1 = (char*)sqlite3_column_text(stmt, 0); 
    myLocation2 = (char*)sqlite3_column_text(stmt, 0); 

    // can process myLocation1 & myLocation2 fine here 

    sqlite3_finalize(stmt); // data myLocation1 points to get corrupted 
    sqlite3_close(db);  // data myLocation2 points to gets further corrupted 

問題與myLocation1有關。它指向的數據很好,直到它遇到sqlite3_finalize和sqlite3_close語句。然而,mylocation2保持不變。所以不知道這裏發生了什麼。執行sqlite3_close(db)後,myLocation1在Visual Studio 2010中被識別爲「Bad Ptr」。

任何幫助最受讚賞。

回答

8

fine manual

const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
[...],直到如上述那樣,或直到sqlite3_step()sqlite3_reset()sqlite3_finalize()被稱爲發生類型轉換
返回的指針是有效的。

因此,一旦你打電話sqlite3_finalize,從sqlite3_column_text的返回值變爲無效,您myLocation1myLocation2指針指向垃圾。

如果您在致電sqlite3_finalize後需要這些字符串,則必須將它們複製到您控制的內存中。實際上,由於是有效的,直到發生類型轉換注意,您應該立即複製它們,並且在製作自己的副本時僅使用(char*)sqlite3_column_text(stmt, 0);

+0

非常感謝。就在那裏,就在「查詢結果值」部分的底部。慚愧地說,我從來沒有讀過那麼遠,但這不是我的藉口。那麼現在所有的東西都是有道理的,因爲sqlite需要通過指針來釋放它首先構造的內存,就像malloc/free一樣。再次感謝你! – owl7 2012-01-10 07:30:11