gpt4 book ai didi

c++ - `boost::serialization::load_construct_data`的实现引发内存访问冲突错误

转载 作者:行者123 更新时间:2023-12-02 10:32:57 27 4
gpt4 key购买 nike

我为没有默认构造函数的类(boost::serialization::save_construct_data)实现了一对boost::serialization::load_construct_datahelib::Context。在boost::serialization::load_construct_data的实现中,我必须调用要序列化的类的一些方法。不幸的是,当我访问指针时,在运行时出现以下错误:

memory access violation at address: 0x00000000: no mapping at fault address

实现如下:

namespace boost{
namespace serialization{

template<class Archive>
inline void save_construct_data(Archive & archive, const helib::Context * context, const unsigned int version){
archive << context->zMStar.getM();
archive << context->zMStar.getP();
archive << context->alMod.getR();
archive << context->smallPrimes;
archive << context->ctxtPrimes;
archive << context->specialPrimes;
archive << context->digits;
}

template<class Archive>
inline void load_construct_data(Archive & archive, helib::Context * context, const unsigned int version){
unsigned long m;
unsigned long p;
unsigned long r;
helib::IndexSet smallPrimes;
helib::IndexSet ctxtPrimes;
helib::IndexSet specialPrimes;
std::vector<helib::IndexSet> digits;
archive >> m;
archive >> p;
archive >> r;
archive >> smallPrimes;
archive >> ctxtPrimes;
archive >> specialPrimes;
archive >> digits;
::new(context)helib::Context(m, p, r);
//restore smallPrimes
for(long prime = smallPrimes.first(); prime <= smallPrimes.last(); prime = smallPrimes.next(prime)){
context->AddSmallPrime(prime);
}
//restore ctxtPrimes
for(long prime = ctxtPrimes.first(); prime <= ctxtPrimes.last(); prime = ctxtPrimes.next(prime))
context->AddCtxtPrime(prime);
//restore specialPrimes
for(long prime = specialPrimes.first(); prime <= specialPrimes.last(); prime = specialPrimes.next(prime))
context->AddSpecialPrime(prime);
//restore digits
context->digits = digits;
//last operation made in buildModchain
context->setModSizeTable();
}

template<class Archive>
void serialize(Archive & archive, helib::Context & context, const unsigned int version){}

}//namespace boost
}//namespace serialization

这是调用代码的测试:

BOOST_AUTO_TEST_CASE(serialization_context)
{
// Plaintext prime modulus
unsigned long p = 4999;
// Cyclotomic polynomial - defines phi(m)
unsigned long m = 32109;
// Hensel lifting (default = 1)
unsigned long r = 1;
// Number of bits of the modulus chain
unsigned long bits = 300;
// Number of columns of Key-Switching matix (default = 2 or 3)
unsigned long c = 2;

helib::Context * original_context_ptr = new helib::Context(m, p, r);
// Modify the context, adding primes to the modulus chain
buildModChain(*original_context_ptr, bits, c);

std::string filename = "context.serialized";

std::ofstream os(filename);
{
boost::archive::text_oarchive oarchive(os);
BOOST_TEST_MESSAGE("(m,p,r): " << original_context_ptr->zMStar.getM() << "," << original_context_ptr->zMStar.getP() << "," << original_context_ptr->alMod.getR());
oarchive << original_context_ptr;
}

helib::Context * restored_context_ptr = new helib::Context(2, 3, 1);
BOOST_TEST_MESSAGE("allocated memory for restored context, address " << restored_context_ptr);
{
std::ifstream ifs(filename);
boost::archive::text_iarchive iarchive(ifs);
iarchive >> restored_context_ptr;
BOOST_TEST_MESSAGE("(m,p,r): " << restored_context_ptr->zMStar.getM() << "," << restored_context_ptr->zMStar.getP() << "," << restored_context_ptr->alMod.getR());
}

BOOST_TEST((*restored_context_ptr == *original_context_ptr));
}

从代码中可以看到,我已经输入了一些消息来尝试诊断问题。运行测试时,会打印出以下内容:
Running 2 test cases...
(m,p,r): 32109,4999,1
allocated memory for restored context, address 0x7fa7c060acb0
context instantiated, address 0x7fa7c060bff0
unknown location:0: fatal error: in "serialization_context": memory access violation at address: 0x00000000: no mapping at fault address
/Users/gianca/electronic-voting-poc/serialization.hpp:68: last checkpoint: adding small prime 0
Test is aborted
Test is aborted

两件事情:
  • 以上消息中的最后一个检查点信息表明,在context->AddSmallPrime(prime);函数内执行load_construct_data时发生错误。 (为清楚起见,我从上面的代码中删除了BOOST_TEST_CHECKPOINT)。
  • 我很惊讶地看到分配给用于接收还原的helib::Context的地址与调用放置新运算符时在boost::serialization::load_construct_data内部使用的地址不同。我期望他们是一样的。但是,我不是专家,我不确定这是否与问题有关。只是想提供更多可能有用的信息。

  • 谢谢你的帮助。

    最佳答案

    我什至为发布问题表示歉意。我的实施存在问题。我在将索引与实际值混淆。正确的方法如下:

    template<class Archive>
    inline void save_construct_data(Archive & archive, const helib::Context * context, const unsigned int version){
    archive << context->zMStar.getM();
    archive << context->zMStar.getP();
    archive << context->alMod.getR();
    archive << context->smallPrimes;
    archive << context->ctxtPrimes;
    archive << context->specialPrimes;
    archive << context->digits;
    auto lastIndexPrime = context->allPrimes().last();
    std::vector<long> primes(lastIndexPrime + 1);
    for(auto index = context->smallPrimes.first(); index <= context->smallPrimes.last(); index = context->smallPrimes.next(index))
    primes[index] = context->ithPrime(index);
    for(auto index = context->ctxtPrimes.first(); index <= context->ctxtPrimes.last(); index = context->ctxtPrimes.next(index))
    primes[index] = context->ithPrime(index);
    for(auto index = context->specialPrimes.first(); index <= context->specialPrimes.last(); index = context->specialPrimes.next(index))
    primes[index] = context->ithPrime(index);
    archive << primes;
    }

    template<class Archive>
    inline void load_construct_data(Archive & archive, helib::Context * context, const unsigned int version){
    unsigned long m;
    unsigned long p;
    unsigned long r;
    helib::IndexSet smallPrimes;
    helib::IndexSet ctxtPrimes;
    helib::IndexSet specialPrimes;
    std::vector<helib::IndexSet> digits;
    std::vector<long> primes;
    archive >> m;
    archive >> p;
    archive >> r;
    archive >> smallPrimes;
    archive >> ctxtPrimes;
    archive >> specialPrimes;
    archive >> digits;
    archive >> primes;
    ::new(context)helib::Context(m, p, r);
    //restore smallPrimes
    for(long index = smallPrimes.first(); index <= smallPrimes.last(); index = smallPrimes.next(index))
    context->AddSmallPrime(primes[index]);
    //restore ctxtPrimes
    for(long index = ctxtPrimes.first(); index <= ctxtPrimes.last(); index = ctxtPrimes.next(index))
    context->AddCtxtPrime(primes[index]);
    //restore specialPrimes
    for(long index = specialPrimes.first(); index <= specialPrimes.last(); index = specialPrimes.next(index))
    context->AddSpecialPrime(primes[index]);
    //restore digits
    context->digits = digits;
    //last operation made in buildModchain
    endBuildModChain(*context);
    }

    关于c++ - `boost::serialization::load_construct_data`的实现引发内存访问冲突错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61617021/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com