2017-01-19 8 views
1

Я использую базу данных lmdb в своем проекте, у меня есть проблема с получением данных с помощью функции mdb_get lmdb ... Я уверен, что mdb_put работает правильно, но функция get объединяет некоторые мусора с моими данными ...Плохое извлечение в LMDB Get?

std::string Get(std::string key) 
{ 
    int rc=0; 
    char *c_key=(char *)key.c_str(); 
    MDB_val d_key,data; 
    data.mv_data = nullptr; 
    data.mv_size = 0; 
    MDB_txn *txn = nullptr; 
    rc = mdb_txn_begin(env_, NULL,MDB_RDONLY, &txn); 
    rc = mdb_dbi_open(txn,NULL, 0, &dbi_); 
    d_key.mv_size = key.size(); 
    d_key.mv_data = c_key; 
    rc= mdb_get(txn,dbi_,&d_key,&data); 
    if (rc) { 
    std::cout<<"Data Can't be Found, Error: "<<mdb_strerror(rc); 
    mdb_dbi_close(env_,dbi_); 
    return ""; 
    } 
    else if(rc==0) 
     std::cout<<"Data Found.\n"; 
    mdb_dbi_close(env_,dbi_); 
    return (char *)data.mv_data; 
} 

возвращенный str содержит мусор, например, str должен содержать «w ah n», но когда я его извлек, mdb_get возвращает «w ah n \ 0004», он объединяет мусор после символа строки null.

ответ

1

Проблема эта линия:

return (char *)data.mv_data; 

Поскольку data.mv_data на самом деле просто куча байтов не строка завершается нулем. Если вы просто бросите его на char*, вы можете получить мусор в конце строки.

Решение должно копировать: data.mv_size bytes от data.mv_data до вновь выделенного char*. В качестве альтернативы вы можете передать указатель назначения как параметр out вашего метода Get.

По крайней мере, это мое решение.

+0

Вы правы, изменили эту строку на: std :: string str ((char *) data.mv_data, data.mv_size); и он работает сейчас. –