如何从BSON反序列化到基本结构-ANSIC

如何从BSON反序列化到基本结构-ANSIC,c,mongodb,bson,C,Mongodb,Bson,我正在构建一个应用程序,它使用mongodb来存储一些数据。我的问题是,当我想反序列化我从mongo得到的BSON时,我从valgrind得到一些警告,所以我认为我在“反序列化”时可能做错了什么 守则: 我创建了一个函数,该函数接收bson并返回我自己的结构: typedef struct { char id[25]; char *name; char *parentId; } dir_t; dir_t* dir_getDirFromBSON(const bson_t

我正在构建一个应用程序,它使用mongodb来存储一些数据。我的问题是,当我想反序列化我从mongo得到的BSON时,我从valgrind得到一些警告,所以我认为我在“反序列化”时可能做错了什么

守则:

我创建了一个函数,该函数接收bson并返回我自己的结构:

typedef struct {
    char id[25];
    char *name;
    char *parentId;
} dir_t;

dir_t* dir_getDirFromBSON(const bson_t *doc) {
    bson_iter_t iter;
    const bson_value_t *value;
    const char *key;
    dir_t *dir = dir_create();

    if (bson_iter_init(&iter, doc)) {
        while (bson_iter_next(&iter)) {
            key = bson_iter_key(&iter);
            value = bson_iter_value(&iter);

            if (strcmp(key, "_id") == 0) {
                strcpy(dir->id, value->value.v_utf8.str);
            } else if (strcmp(key, "name") == 0) {
                strcpy(dir->name, value->value.v_utf8.str);
            } else if (strcmp(key, "parentId") == 0) {
                strcpy(dir->parentId, value->value.v_utf8.str);
            }


        }
    }

    return dir;
}

dir_t* dir_create() {
    dir_t* dir = malloc(sizeof(dir_t));
    dir->name = malloc(sizeof(char) * 512);
    dir->parentId = malloc(sizeof(char) * 25);
    return dir;
}
我将ID设置为db中的字符串,因此没有问题。但是valgrind给了我很多这样的错误:

==10898== Invalid read of size 1
==10898==    at 0x402D4F1: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==10898==    by 0x804AEFB: dir_getDirFromBSON (dir.c:33)
==10898==    by 0x804A4DB: mongo_dir_getByNameInDir (mongo_dir.c:75)
==10898==    by 0x8049601: resolveDir (console.c:192)
==10898==    by 0x8049A3F: changeDir (console.c:322)
==10898==    by 0x804917D: startConsole (console.c:82)
==10898==    by 0x804AFEB: main (main.c:26)
==10898==  Address 0x4289985 is 101 bytes inside a block of size 1,024 free'd
==10898==    at 0x402B3D8: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==10898==    by 0x40665F9: bson_realloc (in /usr/local/lib/libbson-1.0.so.0.0.0)
==10898==    by 0x4066632: bson_realloc_ctx (in /usr/local/lib/libbson-1.0.so.0.0.0)
==10898==    by 0x4083C98: _mongoc_buffer_destroy (in /usr/local/lib/libmongoc-1.0.so.0.0.0)
==10898==    by 0x408EF15: _mongoc_cursor_destroy (in /usr/local/lib/libmongoc-1.0.so.0.0.0)
==10898==    by 0x408F044: mongoc_cursor_destroy (in /usr/local/lib/libmongoc-1.0.so.0.0.0)
==10898==    by 0x804A190: mongo_getDocByQuery (mongo.c:99)
==10898==    by 0x804A4C7: mongo_dir_getByNameInDir (mongo_dir.c:73)
==10898==    by 0x8049601: resolveDir (console.c:192)
==10898==    by 0x8049A3F: changeDir (console.c:322)
==10898==    by 0x804917D: startConsole (console.c:82)
==10898==    by 0x804AFEB: main (main.c:26)
图中显示的第33行是:

strcpy(dir->parentId, value->value.v_utf8.str);
在读取其他字符串的其他行中有很多错误

“反序列化”完成得很完美,但这些错误让我很恼火,我想我可能是在用一种糟糕的方式读取字符串

问题是:

有更好的方法吗? 我做错什么了吗? 为什么valgrind会抛出这些错误?
我应该迭代所有的键还是有办法从键中获取值?

strcpy()
使用固定大小的目标缓冲区是一个非常糟糕的主意!它在大多数情况下可能有效,但在某些数据上会失败。。。(这将为经典的缓冲区溢出安全漏洞打开大门)。那么您有什么建议?要在strcpy()之前获得大小并在其中执行malloc()?准确地说-这在您的情况下应该很容易完成。为简单起见,您可以删除所有
malloc()
s,然后将您的id设置为
char*
而不是
char[25]
,然后使用
strdup()
而不是
strcpy()
。但是,还要确保尊重你的交易。