2016-09-04 16 views
1

버클리 DB를 사용하여 간단한 키/데이터 쌍을 저장하고 가져 오려고하지만 예상대로 작동하지 않습니다. 하나의 함수 (putdb())를 만들어 데이터베이스에 키/데이터 쌍을 만들고 다른 하나 (getdb())는이 쌍을 검색합니다.Berkeley DB는 db를 닫지 않고 데이터에 액세스 할 수 없습니다.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <db.h> 
DB *dbp; 
void opendb(void) 
{ 
     int ret; 
     if ((ret = db_create(&dbp, NULL, 0)) != 0) 
       exit(EXIT_FAILURE); 
     if ((ret = dbp->open(dbp, NULL, "db.db", NULL,DB_BTREE, DB_CREATE, 0664)) != 0) 
       exit(EXIT_FAILURE); 
} 


void putdb(const char *key, const char *value) 
{ 
    DBT keyValue, dataValue; 
    memset(&keyValue, 0, sizeof(keyValue)); 
    memset(&dataValue, 0, sizeof(dataValue)); 

    keyValue.size = sizeof(key); 
    dataValue.size = sizeof(value); 

    keyValue.data = malloc(keyValue.size); 
    strcpy(keyValue.data,key); 

    dataValue.data = malloc(dataValue.size); 
    strcpy(dataValue.data,value); 

    if ((ret = dbp->put(dbp, NULL, &keyValue, &dataValue, 0)) == 0) 
      printf("db: %s: key stored.\n", (char *)keyValue.data); 
    else { 
      dbp->err(dbp, ret, "DB->put"); 
    } 
    dbp->sync(dbp, 0); 
} 

void getdb(const char *key,const char *value) 
{ 
    DBT keyValue, dataValue; 
    memset(&keyValue, 0, sizeof(keyValue)); 
    memset(&dataValue, 0, sizeof(dataValue)); 

    keyValue.size = sizeof(key); 
    dataValue.size = sizeof(value); 

    keyValue.data = malloc(keyValue.size); 
    strcpy(keyValue.data,key); 

    dataValue.data = malloc(dataValue.size); 
    strcpy(dataValue.data,value); 

    if ((ret = dbp->get(dbp, NULL, &keyValue, &dataValue, 0)) == 0) 
      printf("db: %s: key retrieved: data was %s.\n", 
       (char *)keyValue.data, (char *)dataValue.data); 
    else { 
      dbp->err(dbp, ret, "DB->get"); 
    } 
} 
void closedb(void) 
{ 
    dbp->close(dbp, 0); 
    //TODO : error code return check 
} 

및 주 파일 :

int main() 
{ 
    opendb(); 
    putdb("toto","titi"); 
    getdb("toto","titi"); 
    closedb(); 
} 

내가 얻을 :

db: toto: key stored. 
DB->get: BDB0073 DB_NOTFOUND: No matching key/data pair found 

그 이유를 설명 할 수 있습니까? 내 주요 기능을 변경하는 경우

주의 사항 :

int main() 
{ 
    opendb(); 
    putdb("toto","titi"); 
    closedb(); 
    opendb(); 
    getdb("toto","titi"); 
    closedb(); 
} 

후 작동! :

db: toto: key stored. 
db: toto: key retrieved: data was titi. 
+0

어떤 이유에서 strlen(key)를 사용할 수 있나요? – Olaf

+1

32 비트 플랫폼을 사용하는 경우 정의되지 않은 동작 인 할당 범위를 벗어납니다. 64 비트 아키텍처에서는 UB이기도 한 초기화되지 않은 메모리를 읽으므로 키를 찾을 수없는 오류가 발생할 가능성이 큽니다. 모든 경우에 당신은 기억을 새고 있습니다. 문제를 해결할 수는 있지만 문제를 해결할 수도 있습니다. – rici

답변

3

자습서에서 너무 많이 복사했습니다. 그들은 sizeof("a string") 사용할 수 있지만 당신은 C++ 태그를 추가 모두 putdbgetdb

keyValue.size = strlen(key); 
dataValue.size = strlen(value); 
+1

일반적으로 * 키를 검색 할 때 * 데이터 값을 제공하지 않습니다. 'getdb ("key", "value")'는 OP가 데이터 저장소에 대해 좀 더 알 필요가 있음을 암시합니다. :) – rici

+1

@rici yepp "내가 튜토리얼에서 너무 많이 복사했습니다." 조금 미묘한가? – deamentiaemundi

+1

어떤 튜토리얼을 참조하고 있는지 모르겠다. 예를 들어, malloc snd strcpy가 복사 되었다면 아주 나쁜 튜토리얼이며 가능한 한 빨리 불행에서 벗어나야한다. 안타깝게도 이러한 교과서는 존재하지만, 과도한 복제가 아니라 오히려 지나치게 정교화 된 사례라고 생각합니다. 아마도 이전에 동화 된 일부 종파에 기반했을 것입니다. 어쨌든, 최소한의 해독제는 아마도 복사가 가능한 간단한 예일 것입니다. – rici