代码之家  ›  专栏  ›  技术社区  ›  Ben Usman

C++:强制空翻*和后退

  •  3
  • Ben Usman  · 技术社区  · 16 年前

    *---编辑-现在整个源*

    当我最后调试它时,“get”和“value”有不同的值!可能,我转换为void*并以错误的方式返回用户?

    #include <db_cxx.h>
    #include <stdio.h>
    
    struct User{
    User(){}
    int name;
    int town;
    User(int a){};
    inline int get_index(int a){
        return town;
    } //for another stuff
    };
    int main(){ 
    try {
    DbEnv* env = new DbEnv(NULL);
    env->open("./", 
        DB_CREATE | DB_INIT_MPOOL | DB_THREAD | 
    DB_INIT_LOCK | DB_INIT_TXN | DB_RECOVER | DB_INIT_LOG, 0);
    Db* datab = new Db(env, 0);
    datab->open(NULL, "db.dbf", NULL, DB_BTREE, DB_CREATE | DB_AUTO_COMMIT, 0);
    
    Dbt key, value, get;
    char a[10] = "bbaaccd";
    User u;
    u.name = 1;
    u.town = 34;
    key.set_data(a);
    key.set_size(strlen(a) + 1 );
    value.set_data((void*)&u);
    value.set_size(sizeof(u));
    get.set_flags(DB_DBT_MALLOC);
    
    DbTxn* txn;
    env->txn_begin(NULL, &txn, 0);
    datab->put(txn, &key, &value, 0);
    datab->get(txn, &key, &get, 0);
    txn->commit(0);
    User g;
    g = *((User*)&get);
    printf("%d", g.town);
    getchar();
    return 0;
    }catch (DbException &e){
        printf("%s", e.what());
        getchar();
    }
    

    解决方案

    创建一种“序列化器”,将所有的pod转换成void*然后将这些部分结合起来。

    或者我把用户改写成pod类型,我希望一切都会好起来。

    添加

    很奇怪,但是…我将一个非pod对象强制转换为void*和back(里面有std::string),这样就可以了(不需要将其发送到db和back)。怎么可能?在我调用并发送'pou'db defenetly pod对象(没有额外的方法,所有成员都是pod,这是一个简单的结构int a;int b;…)之后,我返回了dirted对象。我的方法怎么了?

    在第一个“添加”后大约一周添加

    该死。。。我已经编译了它,只是为了看看它会返回哪种污垢,哦!没关系!……我不能!……啊!..。上帝……一个合理的问题(99.999%的情况下,正确的答案是“我的”,但是……这里…)-这是谁的错?我的还是VSS?

    4 回复  |  直到 16 年前
        1
  •  7
  •   Nikolai Fetissov    16 年前

    除非 User 是一个 POD 这在C++中是未定义的。

    编辑:

    看着 db_cxx.h 你不应该打电话吗 get_doff() , get_dlen() ,和 get_data() 或者其他什么 Dbt 而不是将其强制转换(并分配)到用户类型?

        2
  •  1
  •   wallyk    16 年前

    由于没有检查put()的返回值,很可能存在阻止更新的错误。 The documentation 表示相当多的错误条件:

        3
  •  1
  •   Darryl    16 年前

    您几乎绝对不应该将“get”直接强制转换为用户。相反,提取存储的数据,然后进行强制转换。除非你和我们分享DBT的定义,否则我们无法确定。根据我们 可以 见:

    datab->get(txn, &key, &get, 0);
    void* data = get.get_data();
    User g = *((User*)data);
    

    告诉我们更多关于DBT的信息,我们可能会帮助您。

        4
  •  0
  •   Loki Astari    16 年前

    我会这样做:

    User               user;
    std::stringstream  dbStotrStream;
    
    dbStoreStream << user;  // Serialize user
    std::string        dbStore(bdStoreStream.str());
    value.set_data(dbStore.c_str());  
    value.set_size(dbStore.lenght());
    
    ////  Put in DB
    

    然后将其提取如下:

    //// Get from DB
    
    std::string        dbStore(get.get_data(),get.get_date() + get.get_size());
    std::stringstream  dbStoreStream(dbStore);
    User              outUser;
    
     dbStoreStream >> outUSer;