2016-07-08 2 views
1

コードの唯一の違いは、データの初期化です。これは動作します:Berkeley DBは異なるDbt初期化で値を設定できません

 Dbt key, data(&b, sizeof(int)); 
     key.set_data(&a); 
     key.set_ulen(sizeof(int)); 
     data.set_flags(DB_DBT_USERMEM); 

が、これはそうではない:

 Dbt key, data; 
     key.set_data(&a); 
     key.set_ulen(sizeof(int)); 
     data.set_data(&b); 
     data.set_ulen(sizeof(int)); 
     data.set_flags(DB_DBT_USERMEM); 

私はhttps://docs.oracle.com/cd/E17076_04/html/api_reference/CXX/dbt.htmlで文書に読んで、私はこれらの2つの方法の違いを見ていません。ややこしい。

完全なコードと結果は以下の通りである:

$ cat db.cpp 

#include <db.h> 
#include <db_cxx.h> 
#include <exception> 
#include <iostream> 
using namespace std; 

int main() { 
     Db db(NULL, 0); 
     u_int32_t oFlags = DB_CREATE | DB_TRUNCATE; 
     try { 
      db.open(NULL, "test.db", NULL, DB_HASH, oFlags, 0); 
     } catch (DbException &e) { 
      cout << "DbException" << endl; 
     } catch (std::exception &e) { 

     } 
     int a = 5, b = 6, c = 0, result[1]= {-1}; 
     Dbt key, data(&b, sizeof(int)); 
     key.set_data(&a); 
     key.set_ulen(sizeof(int)); 
     data.set_flags(DB_DBT_USERMEM); 
     cout << (db.get(NULL, &key, &data, 0) == DB_NOTFOUND) << endl; 
     cout << c << endl; 
     db.put(NULL, &key, &data, 0); 
     key.set_data(&a); 
     data.set_data(result); 
     data.set_ulen(sizeof(int)); 
     cout << (db.get(NULL, &key, &data, 0))<< endl; 
     cout << *((int *) data.get_data()) << endl; 
     cout << result[0] << endl; 
     return 0; 
} 

$ rm test.db ; g++ db.cpp -ldb_cxx-5.1; ./a.out 
1 
0 
0 
6 
6 

$ cat db.cpp 

#include <db.h> 
#include <db_cxx.h> 
#include <exception> 
#include <iostream> 
using namespace std; 

int main() { 
     Db db(NULL, 0); 
     u_int32_t oFlags = DB_CREATE | DB_TRUNCATE; 
     try { 
      db.open(NULL, "test.db", NULL, DB_HASH, oFlags, 0); 
     } catch (DbException &e) { 
      cout << "DbException" << endl; 
     } catch (std::exception &e) { 

     } 
     int a = 5, b = 6, c = 0, result[1]= {-1}; 
     Dbt key, data; 
     key.set_data(&a); 
     key.set_ulen(sizeof(int)); 
     data.set_data(&b); 
     data.set_ulen(sizeof(int)); 
     data.set_flags(DB_DBT_USERMEM); 
     cout << (db.get(NULL, &key, &data, 0) == DB_NOTFOUND) << endl; 
     cout << c << endl; 
     db.put(NULL, &key, &data, 0); 
     key.set_data(&a); 
     data.set_data(result); 
     data.set_ulen(sizeof(int)); 
     cout << (db.get(NULL, &key, &data, 0))<< endl; 
     cout << *((int *) data.get_data()) << endl; 
     cout << result[0] << endl; 
     return 0; 
} 

$ rm test.db ; g++ db.cpp -ldb_cxx-5.1; ./a.out 
1 
0 
0 
-1 
-1 

答えて

1

あなたはDbt.set_size()を呼び出す必要があります。 Dbt.set_ulen()は、Dbt.dataが指すメモリの割り当てサイズのみを設定します。 Dbt.sizeには、キーまたはデータの実際に使用されている長さがあります。あなたの第二の例にこれらの呼び出しを追加すると、それを動作させる必要があります。

Dbt key, data; 
    key.set_data(&a); 
    key.set_ulen(sizeof(int)); 
    key.set_size(sizeof(int)); 
    data.set_data(&b); 
    data.set_ulen(sizeof(int)); 
    data.set_size(sizeof(int)); 
    data.set_flags(DB_DBT_USERMEM); 

Dbt keyset_sizeなしですべてのあなたのために働いている理由として、私は全くわかりません。おそらく、スタック上の初期化されていないデータで幸運になるでしょうか?調べたい場合は、key.sizeの値を印刷することができます。

明快にするため、ulenput()より先に設定する必要はありません。 get()を実行する前に設定する必要があるだけで、BDBにデータの読み込みに必要なメモリ量を知らせることができます。

+0

ありがとうございました!あなたは本当に役に立ちました。 – user3458198

関連する問題