c++ - 将字符数组转换为字符串时的意外行为
问题描述
所以我有这个简单的类,它接受一个字符数组并将其解析为一个 JSON 对象。然后它在内部存储该对象并提供一个 getter。
class JSONContainer {
public:
explicit JSONContainer(const char* const json) {
std::string t(json);
_json = new nlohmann::basic_json(json);
}
~JSONContainer() {
delete _json;
}
nlohmann::json *j() {
return _json;
}
private:
nlohmann::json* _json;
};
如果我用一些简单的东西来实例化这个类,比如......
{"data": [100,100]}
它可以工作,但是如果这个字符串增长到 ~1000+ 的长度,当我尝试解析json
为一个字符串时,传入的字符数组就会被破坏。
// incoming json {"data": [100,100,100,100,100...
std::string t(json); // turns into "ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ..." after this line
我不知道是什么原因造成的。我想检查的一件事是结尾处是否存在空终止符,json
我总能找到它。
感谢帮助!
评论的附加上下文...
这是调用上面构造函数的方法...
std::shared_ptr<void> JSONSerDes::deserialize(const char *serializedData) {
auto *ct = new JSONContainer(serializedData);
return std::shared_ptr<void>(ct);
}
然后上堆栈到主函数,注意这一行deserializedData = t->deserialize(serializedData);
...
...
// declare intermediate data
const char* serializedData;
std::shared_ptr<void> deserializedData;
// for each data set size, run each test
for (const int testSize: sizeTestsB) {
// generate the test data, imitate data coming from python program
PyObject* td = data(testSize);
for (const std::unique_ptr<SerDesTest>& t: tests) {
// log the start
startTest(t->type(), testSize, currentTest, totalTests);
// mark start, ser/des mark end
start = std::chrono::steady_clock::now();
serializedData = t->serialize(td); // Python -> Redis
checkpoints.push_back(checkpoint(t->type(), testSize, "PythonToRedis", start));
deserializedData = t->deserialize(serializedData); // Redis -> Container
checkpoints.push_back(checkpoint(t->type(), testSize, "RedisToContainer", start));
...
这是用于将 python 对象转换为字符数组的函数。dumps 是来自 pythons json 模块的一种方法。我可能误解了字符数组的生命周期是什么。
const char* JSONSerDes::serialize(PyObject * pyJson) {
// convert pyobject to boost python object
boost::python::object d = boost::python::extract<boost::python::object>(pyJson);
// call the dumps function and capture the return value
return boost::python::extract<const char*>(dumps(d));
}
解决方案
我发现出了什么问题。当这个手柄
boost::python::object rv = dumps(d);
超出范围数据似乎被删除了,这让我觉得“提取的”指针只是引用内部数据,而不是作为提供的类型复制出来的数据。
我刚刚更改了我的序列化方法以将数据复制到我在堆上分配的新缓冲区。
const char* JSONSerDes::serialize(PyObject * pyJson) {
// convert pyobject to boost python object
boost::python::object d = boost::python::extract<boost::python::object>(pyJson);
// capture the return value of the return value
boost::python::object rv = dumps(d);
const char* prv = boost::python::extract<const char*>(rv);
size_t prvLen = strlen(prv);
// copy and return
char* rvBuffer = new char[prvLen + 1];
rvBuffer[prvLen] = '\0';
strncpy(rvBuffer, prv, strlen(prv));
// call the dumps function and capture the return value
return rvBuffer;
}
推荐阅读
- c - 在动态分配的数组中使用 sprintf 时出现分段错误
- python - 如何从 python 执行命令提示符命令?
- c - CS50 Pset1 Cash 示例 0.01 和 0.15 的错误输出
- android - Android如何创建具有正确方向的位图图像?
- python - Elephas - 无法通过 pip install 安装
- c++ - 如何在 C++ 中使用 websocketpp?
- python - OS .CWD 跳过一个 DIR 如何修复
- angular - 在不打开下拉菜单的情况下触发 ng-select on-blur 事件
- javascript - Angular 路由器解析器与 ngOnInit 获取
- node.js - mongoose-paginate-v2 不在两个方向上排序