Последовательный доступ к GDBM: ошибка?
Я реализовал следующий пример GBDM:
#include <boost/lexical_cast.hpp>
#include <gdbm.h>
#include <iostream>
#include <string>
#include <string.h>
struct record
{
int a;
int b;
};
int main(int argc, char* argv[])
{
GDBM_FILE db;
db = gdbm_open("gdbm.db", 512, GDBM_WRCREAT | GDBM_NOLOCK | GDBM_SYNC, 0664, NULL);
datum lekey;
datum levalue;
for (int i = 0; i < 10; ++i) {
record r;
r.a = i;
r.b = i + 1;
lekey.dptr = (char*) boost::lexical_cast<std::string>(i).c_str();
lekey.dsize = strlen(lekey.dptr) + 1;
levalue.dptr = (char*) &r;
levalue.dsize = sizeof(record);
gdbm_store(db, lekey, levalue, GDBM_INSERT);
}
gdbm_sync(db);
for(lekey = gdbm_firstkey(db);
lekey.dptr != NULL;
lekey = gdbm_nextkey(db, lekey)) {
levalue = gdbm_fetch(db, lekey);
record* r = (record*) levalue.dptr;
if (r) {
std::cout << lekey.dptr << " " << r->a << " " << r->b << std::endl;
free(levalue.dptr);
}
}
gdbm_close(db);
return 0;
}
Вывод следующий:
$ ./gdbm_example
3 3 4
6 6 7
2 2 3
9 9 10
5 5 6
1 1 2
8 8 9
4 4 5
Почему бы 0 0 1
а также 7 7 8
быть оставленным? Это ошибка или я что-то не так делаю?
2 ответа
Решение
Проблема может быть в этой строке:
lekey.dptr = (char*) boost::lexical_cast<std::string>(i).c_str();
Это хранит указатель на временную переменную, и поэтому неопределенное поведение.
Ключ не обязательно должен быть строкой, он также может быть числом, поэтому вы можете использовать, например:
lekey.dptr = &i;
lekey.dsize = sizeof(i);
Йоахим прав, использование boost::lexical_cast здесь неуместно. Перепишите ваш пример, используя это:
std::string s;
std::stringstream str;
str << i;
s = str.str();
lekey.dptr = (char*) s.c_str();
и это будет работать как положено.