2012-01-10 8 views
5

Non sono sicuro di cosa stia succedendo qui, ma sto scoprendo che i dati restituiti da sqlite3_column_text sono stati modificati durante la fase finalize/close sqlite.sqlite3_column_text i dati restituiti vengono danneggiati durante la finalizzazione/chiusura

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

Il problema è relativo a myLocation1. I dati a cui punta va bene finché non raggiunge le istruzioni sqlite3_finalize e sqlite3_close. Tuttavia mylocation2 rimane inalterato. Quindi non sono sicuro di cosa sta succedendo qui. Dopo aver eseguito sqlite3_close (db), myLocation1 viene identificato come "Bad Ptr" in Visual Studio 2010.

Qualsiasi aiuto più apprezzato.

risposta

8

Dal fine manual:

const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
[...]
I puntatori restituiti sono validi finché non si verifica una conversione di tipo come descritto sopra, o fino sqlite3_step() o sqlite3_reset() o sqlite3_finalize() è chiamato.

Così, non appena si chiama sqlite3_finalize, i valori restituiti da sqlite3_column_text più validi e le vostre myLocation1 e myLocation2 puntatori puntare a spazzatura.

Se hai bisogno di quelle stringhe dopo aver chiamato sqlite3_finalize dovrai quindi copiarle nella memoria che controlli. Infatti, a causa della sono validi fino a quando si verifica una conversione di tipo, è necessario copiarli immediatamente e utilizzare solo (char*)sqlite3_column_text(stmt, 0); mentre si stanno facendo le proprie copie.

+0

Grazie mille per quello. Ed eccolo lì, proprio in fondo alla sezione "Risultato dei risultati da una query". Mi vergogno di dire che non ho mai letto così lontano, ma non è una scusa da parte mia. Bene, tutto ha senso ora che sqlite ha bisogno di non allocare memoria costruita in primo luogo tramite i puntatori, proprio come malloc/free. Grazie ancora! – owl7

Problemi correlati