不修改bson_value_t定义时结构体嵌套char指针的内存分配咨询
问题结论
- 在不得修改bson_value_t定义的前提下,你只需要手动为每个需要存储UTF8字符串的bson_value_t实例的
v_utf8.str分配堆内存,同时正确设置字符串长度和类型标记即可实现需求。 - 是的,所有需要存储字符串的bson_value_t实例都需要单独分配内存,每个实例的
str指针是独立的,不会自动分配或共享内存空间。
错误写法原因说明
- 第一种写法:未初始化的
str是野指针,指向非法内存地址,直接调用strcpy会触发段错误,属于典型的访问越界问题。 - 第二种写法:取
str指针自身的内存地址作为写入缓冲区,相当于把存储指针变量的内存(通常只有4/8字节)当做字符串缓冲区使用,写入长度超过指针大小就会破坏后续内存数据,属于严重的未定义行为,能正常运行只是概率性的巧合,随时可能触发崩溃或数据错乱。
正确实现步骤
单实例赋值示例(以single字段为例)
const char *target_str = "test"; // 计算字符串长度(不含末尾结束符\0) uint32_t str_len = strlen(target_str); // 为str分配内存,多分配1字节存储结束符 Datapackage.single.value.value.v_utf8.str = (char *)malloc(str_len + 1); if (Datapackage.single.value.value.v_utf8.str != NULL) { // 拷贝字符串 strcpy(Datapackage.single.value.value.v_utf8.str, target_str); // 赋值字符串长度 Datapackage.single.value.value.v_utf8.len = str_len; // 标记当前bson_value存储的是UTF8字符串,枚举名根据你的bson头文件定义调整,一般为BSON_TYPE_UTF8 Datapackage.single.value.value_type = BSON_TYPE_UTF8; }
批量数组赋值示例(以multiple数组第i个元素为例)
int i = 0; // 要赋值的数组下标 const char *target_str = "batch_test"; uint32_t str_len = strlen(target_str); Datapackage.multiple[i].value.value.v_utf8.str = (char *)malloc(str_len + 1); if (Datapackage.multiple[i].value.value.v_utf8.str != NULL) { strcpy(Datapackage.multiple[i].value.value.v_utf8.str, target_str); Datapackage.multiple[i].value.value.v_utf8.len = str_len; Datapackage.multiple[i].value.value_type = BSON_TYPE_UTF8; }
内存释放注意事项
使用完Datapackage后需要手动释放所有分配的字符串内存,避免内存泄漏:
// 释放single字段的字符串内存 if (Datapackage.single.value.value_type == BSON_TYPE_UTF8 && Datapackage.single.value.value.v_utf8.str != NULL) { free(Datapackage.single.value.value.v_utf8.str); Datapackage.single.value.value.v_utf8.str = NULL; } // 批量释放multiple数组的字符串内存 for (int i = 0; i < 100; i++) { if (Datapackage.multiple[i].value.value_type == BSON_TYPE_UTF8 && Datapackage.multiple[i].value.value.v_utf8.str != NULL) { free(Datapackage.multiple[i].value.value.v_utf8.str); Datapackage.multiple[i].value.value.v_utf8.str = NULL; } }
补充说明
如果你使用的bson库提供了bson_value_set_string之类的封装API,优先调用库函数实现赋值,不需要手动分配内存,能避免手动操作可能出现的错误。
内容的提问来源于stack exchange,提问作者user16921148
相关产品推荐
相关产品推荐

