2016-09-04 6 views
1

J'essaie d'utiliser berkeley DB pour stocker et obtenir des paires de clés/données simples, mais cela ne fonctionne pas comme prévu. Je crée une fonction (putdb()) pour mettre une paire clé/donnée dans la base de données et une autre (getdb()) pour récupérer cette paire.Berkeley DB ne peut pas mettre puis accéder aux données sans fermer 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 
} 

et le fichier principal:

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

et je reçois:

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

Pouvez-vous expliquer pourquoi?

avis si je change ma fonction principale:

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

il fonctionne! :

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

une raison quelconque vous ajouté la balise C++? – Olaf

+1

Si vous utilisez une plateforme 32 bits, vous écrivez en dehors de vos affectations, ce qui correspond à un comportement non défini. Sur les architectures 64 bits, vous lisez la mémoire non initialisée, qui est également UB, et risque fort de générer des erreurs non trouvées. Dans tous les cas, vous fuyez la mémoire. Vous pourriez vouloir corriger ces problèmes, même si cela ne résout pas le problème immeduate (bien que cela puisse être le cas). – rici

Répondre

3

Vous avez trop copié le didacticiel. Ils peuvent utiliser sizeof("a string") mais vous devez utiliser strlen(key) dans les deux putdb et getdb

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

Normalement, vous ne * fournissez * pas de valeur de données lors de * la récupération * d'une clé. 'getdb (" key "," value ")' suggère que OP ne doit pas en savoir un peu plus sur les banques de données. :) – rici

+1

@rici yepp, comme je l'ai noté "Vous avez copié trop du tutoriel". Était-ce un peu trop subtile? – deamentiaemundi

+1

Je ne sais pas de quel tutoriel vous parlez, mais si, par exemple, le malloc snd strcpy a été copié, c'est un très mauvais tutoriel et devrait être mis hors de sa misère à la première occasion possible. Malheureusement, de tels antitutoriaux existent, mais je soupçonne qu'il ne s'agit pas d'une copie excessive mais plutôt d'une élaboration excessive, peut-être basée sur un culte de la marchandise précédemment assimilé. Dans tous les cas, l'antidote minimum est probablement un simple exemple copiable. – rici