1

所以我有这个简单的类,它接受一个字符数组并将其解析为一个 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));
}
4

1 回答 1

0

我发现出了什么问题。当这个手柄

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;
}
于 2021-09-08T05:07:58.767 回答