双重自由或腐败 C++ Avro

问题描述 投票:0回答:1

我需要在 C++ 中使用 Avro 序列化一个 JSON 字符串。 我安装了 libserdes 库(https://github.com/confluentinc/libserdes)并使用了示例代码

./examples/kafka-serdes-avro-console-producer.cpp

写一个主要的, 它按如下方式序列化 JSON 字符串。

{"s":"BTCUSDT","c":"spread","u":123456789,"a":20000.4,"b":21000.5,"A":1.25,"B":0.58,"p":-1,"P":-1,"st":-1,"rt":1675000000123000}

这是代码

#include "fh_price_t.h"
#include "avro/Encoder.hh"
#include "avro/Decoder.hh"
#include <avro/Generic.hh>
#include <avro/Specific.hh>
#include <avro/Exception.hh>

#include "libserdes/serdescpp-avro.h"

#include <iostream>
#include <sstream>
#include <string>
#include <fstream>

#define FATAL(reason...) do { \
    std::cerr << "% FATAL: " << reason << std::endl; \
    exit(1); \
} while (0)


template<class T> std::string to_string_a (const T& x) {
    std::ostringstream oss;
    oss << x;
    return oss.str();
}

/**
 * Convert JSON to Avro Datum.
 *
 * Returns 0 on success or -1 on failure.
 */
int json2avro (Serdes::Schema *schema, const std::string &json,
                      avro::GenericDatum **datump) {

    avro::ValidSchema *avro_schema = schema->object();

    /* Input stream from json string */
    std::istringstream iss(json);
    auto json_is = avro::istreamInputStream(iss);

    /* JSON decoder */
    avro::DecoderPtr json_decoder = avro::jsonDecoder(*avro_schema);
    avro::GenericDatum *datum = new avro::GenericDatum(*avro_schema);

    try {
        /* Decode JSON to Avro datum */
        json_decoder->init(*json_is);
        avro::decode(*json_decoder, *datum);

    } catch (const avro::Exception &e) {
        std::cerr << "% JSON to Avro transformation failed: "
                << e.what() << std::endl;
        return -1;
    }

    *datump = datum;

}

int main (int argc, char* argv) {

    izycoinstestavro::fh_price_t price{};
    price.s = "BTCUSDT";
    price.c = "spread";
    price.u = 123456789;
    price.a = 20000.4;
    price.A = 1.25;
    price.b = 21000.52;
    price.B = 0.58;
    price.p = -1;
    price.P = -1;
    price.st = -1;
    price.rt = 1675000000123000;

    std::ifstream file_ifstream("../src/avro/fh_price_t.json");
    std::stringstream buffer;
    buffer << file_ifstream.rdbuf();
    std::string schema_json = buffer.str();

    Serdes::Conf *sconf = Serdes::Conf::create();
    Serdes::Schema *schema;
    std::string errstr;

    if (sconf->set("schema.registry.url", "http://localhost:8081", errstr))
        FATAL("Conf failed: " << errstr);

    if (sconf->set("serializer.framing", "cp1", errstr))
        FATAL("Conf failed: " << errstr);

    Serdes::Avro *serdes = Serdes::Avro::create(sconf, errstr);
    if (!serdes)
        FATAL("Failed to create Serdes handle: " << errstr);

    schema = Serdes::Schema::add(serdes, "fh_price_t", schema_json, errstr);
    if (!schema)
        FATAL("Failed to register schema " << "fh_price_t" << ": " << errstr);

    std::cout << "% Registered schema " << schema->name() << " with id " << schema->id() << std::endl;


    avro::GenericDatum *datum = NULL;
    std::vector<char> out;

    /* Convert JSON to Avro object */
    std::string line = to_string_a(price);
    json2avro(schema, line, &datum);
    
    //std::cout << to_string_a(price) << std::endl;
    /*if (rr == -1) {
        FATAL("Failed to convert JSON to Avro " << to_string_a(price) << ": " << errstr);
    }

    // Serialize Avro 
    if (serdes->serialize(schema, datum, out, errstr) == -1) {
        std::cerr << "% Avro serialization failed: " << errstr << std::endl;
        delete datum;
        exit(1);
    }
    delete datum;

    std::cout << "Data Size : " << out.size() << std::endl;*/

    return 0;
}

当我运行它时,出现双重释放或损坏 (out) 错误。 错误发生在函数的输出处。 我找到了导致错误的行(因为当我删除它时,错误消失了)

avro::GenericDatum *datum = new avro::GenericDatum(*avro_schema);

我想知道为什么以及如何解决它

c++ serialization apache-kafka g++ avro
1个回答
0
投票

检查“avro-cpp”和“libserdes”是否使用与 C++11/C++17 标准相同的设置进行编译。他们必须匹配:混合配置会导致你的问题。

© www.soinside.com 2019 - 2024. All rights reserved.