1

strcpy、memcpy などを試しましたが、残念ながら、sqlite をファイナライズした後も char データが破損しています。しかし、CString データには何も起こりません。フィールドをファイナライズする前に別のフィールドにコピーする必要があることはわかっていますが、機能しません。代わりに CString データを使用しても安全かどうかもわかりません。

    CString StrDescription;
    char dbDescription1[110+1];

    const char *data = NULL;
    char *SQLString= new char[SQLStr.GetLength()+1] ;
    memset(SQLString,0x00,sizeof(SQLString)-1);wcstombs(SQLString,SQLStr,SQLStr.GetLength());SQLString[SQLStr.GetLength()]='\0';
    if ( sqlite3_prepare_v2( db,SQLString , -1, &stmt, NULL )!= SQLITE_OK)
    {
       sqlite3_finalize( stmt ); sqlite3_close(db); delete[] SQLString; return -1;
    }
    delete[] SQLString;

    if( sqlite3_step( stmt ) == SQLITE_ROW ) 
    {       
        data = (const char*)sqlite3_column_text( stmt, 4 ); sprintf(dbDescription1 ,"%s",data); 
        StrDescription = CString(data);
    }    

    AfxMessageBox(CString(dbDescription)); // Result is ok here..
    AfxMessageBox(StrDescription); // Result is ok here as well.

    sqlite3_finalize( stmt );  sqlite3_close(db);

    AfxMessageBox(CString(dbDescription)); // Result corrupt here
    AfxMessageBox(StrDescription); // Result still ok 


    Thanks
4

2 に答える 2

1

これは、StrDescription が文字列のコピーを保持しているためだと思われますが、Sqlite が dbDescription1 が指すメモリのクリーンアップが完了した後も機能します。したがって、この状況では CString を使用することは安全であり、文字列クラス (CString または std::string など) であるため、このような場合は C の方法で (strcpy/strncpy などを使用して) コピーを作成するよりも優先されます。簡単に間違えるのを防いでくれます。

于 2012-11-15T15:42:55.793 に答える
0

SQLite は列制限をチェックしないため、110 文字を超える可能性があります。

さらに、UTF-8 では、文字は必ずしもバイトと同じではないため、110 バイトを超える可能性があります。

sqlite3_column_bytesまたはstrlenを使用して、割り当てる必要があるバッファーの大きさを確認するか、単に as バッファーを使用しますCString

于 2012-11-13T14:46:36.163 に答える