2012-01-10 14 views
5

Nie jestem pewien, co się tutaj dzieje, ale stwierdzam, że zwracane dane z sqlite3_column_text są zmieniane podczas fazy finalizacji/zamykania sqlite.sqlite3_column_text Zwrócone dane zostają uszkodzone podczas finalizowania/zamykania

// 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 

Problem związany jest z myLocation1. Dane, na które wskazuje, są w porządku, dopóki nie trafią do instrukcji sqlite3_finalize i sqlite3_close. Jednak mylokacja2 pozostaje niezmieniona. Więc nie jestem pewien, co się tutaj dzieje. Po wykonaniu sqlite3_close (db), myLocation1 jest identyfikowany jako "Bad Ptr" w Visual Studio 2010.

Każda pomoc najbardziej ceniona.

Odpowiedz

8

Z fine manual:

const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
[...]
Wskaźniki zwracane są ważne do konwersji typu występuje w sposób opisany powyżej, lub aż sqlite3_step() lub sqlite3_reset() lub sqlite3_finalize() nazywa.

Więc jak najszybciej zadzwonić sqlite3_finalize wartości powrotne od sqlite3_column_text stają się nieważne i twoi myLocation1 i myLocation2 wskaźniki wskazują na śmieci.

Jeśli potrzebujesz tych ciągów po wywołaniu sqlite3_finalize, będziesz musiał skopiować je do pamięci, którą kontrolujesz. W rzeczywistości, z powodu są ważne, dopóki nie nastąpi konwersja typu Uwaga, powinieneś skopiować je natychmiast i używać tylko (char*)sqlite3_column_text(stmt, 0); podczas tworzenia własnych kopii.

+0

Dziękuję bardzo za to. I tak właśnie było, na samym dole sekcji "Wartości wyników z zapytania". Wstydzę się powiedzieć, że nigdy nie czytałem tak daleko, ale to nie jest żadna wymówka z mojej strony. Cóż, wszystko ma teraz sens, ponieważ sqlite musi nieprzydzielać pamięci, którą skonstruował w pierwszej kolejności za pomocą wskaźników, podobnie jak malloc/free. Jeszcze raz dziękuję! – owl7

Powiązane problemy