从SQLite的斑点中读取垃圾

我有一小段代码,以某种方式弄乱了sqlite数据库的字节读取。我经历过多次:首先使用PNG,后三个字节不同,其次使用国王詹姆斯圣经,其次使用非常简单的测试用例。我感到困惑的是我在哪里。在所有这些情况下,命令行sqlite工具都可以正确查看数据库内部的数据(手动查看和使用writefile均可)。

因此插入操作一定可以正确地进行,只是由于某种原因我的提取是错误的。我是C语言的新手,所以我希望我可能以某种方式分配了错误的内存,我只是不知道如何。

#include <stdio.h>
#include <sqlite3.h>
#include <stdlib.h>

static char const dummy_content[] = 
"hello world more \n\n\n hello worlds \nlalalala";


int 
main(int argc,char **argv) {
    sqlite3 *db;
    sqlite3_stmt *stmt;
    int rc,file_len,sqlite_len;
    const char *file_contents;
    const char *sqlite_contents;

    rc = sqlite3_open("blah.db",&db);

    if ( rc ) {
        fprintf(stderr,"couldn't open db\n");
        return 1;
    }

    /* initialise the schema */
    rc = sqlite3_exec(db,"BEGIN TRANSactION;"
                "DROP TABLE IF EXISTS blobs;" 
            "CREATE TABLE blobs(id TEXT NOT NULL,value BLOB,PRIMARY KEY(id));"
                "COMMIT;",NULL,NULL);

    if ( rc ) {
        fprintf(stderr,"couldn't initialise schema");
        return 1;
    }

    file_contents = dummy_content;
    file_len = sizeof(dummy_content);

    /* insert the bytes */
    rc = sqlite3_prepare_v2(db,"INSERT INTO blobs VALUES(?,?);",-1,&stmt,"error preparing stmt: %s",sqlite3_errmsg(db));
        return 1;
    }

    printf("prepared stmt\n");

    rc = sqlite3_bind_text(stmt,1,"boring",NULL);
    rc = rc | sqlite3_bind_blob(stmt,2,file_contents,NULL);
    if ( rc ) {
        fprintf(stderr,"error binding to sql stmt");
        return 1;
    }

    if ( (rc = sqlite3_step(stmt)) != SQLITE_DONE) {
        fprintf(stderr,"something went wrong with execution");
    }

    sqlite3_finalize(stmt);

    if ( rc != SQLITE_DONE ) return 1;

    printf("loaded db\n");

    /* load the  bytes */
    rc = sqlite3_prepare_v2(db,"SELECT value FROM blobs WHERE id = ?;",sqlite3_errmsg(db));
        return 1;
    }

    rc = sqlite3_bind_text(stmt,NULL);

    if ( rc ) { fprintf(stderr,"error binding"); return 1; }

    sqlite_len = -1;
    while ( (rc = sqlite3_step(stmt)) != SQLITE_DONE ) {
        if ( rc == SQLITE_ERROR ) {
            fprintf(stderr,"error executing sql");
            sqlite3_finalize(stmt);
            return 1;
        } else if ( rc == SQLITE_ROW ) {
            sqlite_contents = sqlite3_column_blob(stmt,0);
            sqlite_len = sqlite3_column_bytes(stmt,0);
        }
    }

    if ( sqlite_len < 0 ) {
        fprintf(stderr,"no value found in db");
        sqlite3_finalize(stmt);
        return 1;
    }

    printf("sqlite_len: %i file_len: %i\n",sqlite_len,file_len);
    printf("from file string: %s\n",file_contents);
    printf("from sqlite string: %s\n",sqlite_contents);

    /* this frees the memory for the sqlite_contents */
    sqlite3_finalize(stmt);
    return 0;
}
chouyangheng 回答:从SQLite的斑点中读取垃圾

您只能使用sqlite3_column_blob()返回的值,直到下次调用sqlite3_step()为止。您的代码没有遵守该限制(您试图在再次调用sqlite3_step()返回SQLITE_DONE之后打印出blob)

来自the documentation

  

返回的指针有效,直到如上所述发生类型转换,或者直到调用sqlite3_step()或sqlite3_reset()或sqlite3_finalize()为止。

本文链接:https://www.f2er.com/3163596.html

大家都在问