Увеличение утечек памяти при сериализации - PullRequest
1 голос
/ 22 марта 2019

Я получаю следующую странную ошибку после запуска моего кода с использованием Boost serialization library .

==11589==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 32 byte(s) in 1 object(s) allocated from:
    #0 0x558c3cf36550 in operator new(unsigned long) (/home/martin/myProg/build/bin/examples/myScript_1_2+0x11f550)                                                                         
    #1 0x558c3d0cd14d in boost::archive::detail::heap_allocation<DoubleUnitStrategy>::doesnt_have_new_operator::invoke_new() /home/martin/myProg/external_dependencies/boost/boost/archive/detail/iserializer.hpp:241
    #2 0x558c3d0cce8b in boost::archive::detail::heap_allocation<DoubleUnitStrategy>::invoke_new() /home/martin/myProg/external_dependencies/boost/boost/archive/detail/iserializer.hpp:255
    #3 0x558c3d0ccd54 in boost::archive::detail::heap_allocation<DoubleUnitStrategy>::heap_allocation() /home/martin/myProg/external_dependencies/boost/boost/archive/detail/iserializer.hpp:268
    #4 0x558c3d0ccb3d in boost::archive::detail::pointer_iserializer<boost::archive::text_iarchive, DoubleUnitStrategy>::heap_allocation() const /home/martin/myProg/external_dependencies/boost/boost/archive/detail/iserializer.hpp:293
    #5 0x558c3d1030c9 in boost::archive::detail::basic_iarchive_impl::load_pointer(boost::archive::detail::basic_iarchive&, void*&, boost::archive::detail::basic_pointer_iserializer const*, boost::archive::detail::basic_pointer_iserializer const* (*)(boost::serialization::extended_type_info const&)) (/home/martin/myProg/build/bin/examples/myScript_1_2+0x2ec0c9)
    #6 0x558c3d101cd9 in boost::archive::detail::basic_iarchive::load_pointer(void*&, boost::archive::detail::basic_pointer_iserializer const*, boost::archive::detail::basic_pointer_iserializer const* (*)(boost::serialization::extended_type_info const&)) libs/serialization/src/basic_iarchive.cpp:573
    #7 0x558c3cfc8a2b in void boost::archive::detail::load_pointer_type<boost::archive::text_iarchive>::invoke<NormalizationStrategy*>(boost::archive::text_iarchive&, NormalizationStrategy*&) /home/martin/myProg/external_dependencies/boost/boost/archive/detail/iserializer.hpp:541
    #8 0x558c3cfc80c5 in void boost::archive::load<boost::archive::text_iarchive, NormalizationStrategy*>(boost::archive::text_iarchive&, NormalizationStrategy*&) /home/martin/myProg/external_dependencies/boost/boost/archive/detail/iserializer.hpp:624
    #9 0x558c3cfc7a5b in void boost::archive::detail::common_iarchive<boost::archive::text_iarchive>::load_override<NormalizationStrategy*>(NormalizationStrategy*&) /home/martin/myProg/external_dependencies/boost/boost/archive/detail/common_iarchive.hpp:67
    #10 0x558c3cfc75c4 in void boost::archive::basic_text_iarchive<boost::archive::text_iarchive>::load_override<NormalizationStrategy*>(NormalizationStrategy*&) /home/martin/myProg/external_dependencies/boost/boost/archive/basic_text_iarchive.hpp:70
    #11 0x558c3cfc6f9c in void boost::archive::text_iarchive_impl<boost::archive::text_iarchive>::load_override<NormalizationStrategy*>(NormalizationStrategy*&) /home/martin/myProg/external_dependencies/boost/boost/archive/text_iarchive.hpp:82
    #12 0x558c3cfc6a01 in boost::archive::text_iarchive& boost::archive::detail::interface_iarchive<boost::archive::text_iarchive>::operator>><NormalizationStrategy*>(NormalizationStrategy*&) /home/martin/myProg/external_dependencies/boost/boost/archive/detail/interface_iarchive.hpp:68
    #13 0x558c3cfc5d8d in boost::archive::text_iarchive& boost::archive::detail::interface_iarchive<boost::archive::text_iarchive>::operator&<NormalizationStrategy*>(NormalizationStrategy*&) (/home/martin/myProg/build/bin/examples/myScript_1_2+0x1aed8d)
    #14 0x558c3cfc4ffd in void myProg::NeuralNetwork::access::serialize<boost::archive::text_iarchive>(boost::archive::text_iarchive&, myProg::NeuralNetwork&, unsigned int) (/home/martin/myProg/build/bin/examples/myScript_1_2+0x1adffd)
    #15 0x558c3cfc3bfe in void boost::serialization::serialize<boost::archive::text_iarchive>(boost::archive::text_iarchive&, myProg::NeuralNetwork&, unsigned int) (/home/martin/myProg/build/bin/examples/myScript_1_2+0x1acbfe)
    #16 0x558c3cfc2307 in void boost::serialization::serialize_adl<boost::archive::text_iarchive, myProg::NeuralNetwork>(boost::archive::text_iarchive&, myProg::NeuralNetwork&, unsigned int) (/home/martin/myProg/build/bin/examples/myScript_1_2+0x1ab307)
    #17 0x558c3cfc0775 in boost::archive::detail::iserializer<boost::archive::text_iarchive, myProg::NeuralNetwork>::load_object_data(boost::archive::detail::basic_iarchive&, void*, unsigned int) const (/home/martin/myProg/build/bin/examples/myScript_1_2+0x1a9775)
    #18 0x558c3d102bae in boost::archive::detail::basic_iarchive_impl::load_object(boost::archive::detail::basic_iarchive&, void*, boost::archive::detail::basic_iserializer const&) (/home/martin/myProg/build/bin/examples/myScript_1_2+0x2ebbae)
    #19 0x558c3d101c90 in boost::archive::detail::basic_iarchive::load_object(void*, boost::archive::detail::basic_iserializer const&) libs/serialization/src/basic_iarchive.cpp:560
    #20 0x558c3cfbee1a in void boost::archive::detail::load_non_pointer_type<boost::archive::text_iarchive>::load_standard::invoke<myProg::NeuralNetwork>(boost::archive::text_iarchive&, myProg::NeuralNetwork const&) (/home/martin/myProg/build/bin/examples/myScript_1_2+0x1a7e1a)
    #21 0x558c3cfbca4c in void boost::archive::detail::load_non_pointer_type<boost::archive::text_iarchive>::invoke<myProg::NeuralNetwork>(boost::archive::text_iarchive&, myProg::NeuralNetwork&) (/home/martin/myProg/build/bin/examples/myScript_1_2+0x1a5a4c)
    #22 0x558c3cfb9f24 in void boost::archive::load<boost::archive::text_iarchive, myProg::NeuralNetwork>(boost::archive::text_iarchive&, myProg::NeuralNetwork&) (/home/martin/myProg/build/bin/examples/myScript_1_2+0x1a2f24)
    #23 0x558c3cfb5d41 in void boost::archive::detail::common_iarchive<boost::archive::text_iarchive>::load_override<myProg::NeuralNetwork>(myProg::NeuralNetwork&) /home/martin/myProg/external_dependencies/boost/boost/archive/detail/common_iarchive.hpp:67
    #24 0x558c3cfaf4fc in void boost::archive::basic_text_iarchive<boost::archive::text_iarchive>::load_override<myProg::NeuralNetwork>(myProg::NeuralNetwork&) /home/martin/myProg/external_dependencies/boost/boost/archive/basic_text_iarchive.hpp:70
    #25 0x558c3cfa7e10 in void boost::archive::text_iarchive_impl<boost::archive::text_iarchive>::load_override<myProg::NeuralNetwork>(myProg::NeuralNetwork&) (/home/martin/myProg/build/bin/examples/myScript_1_2+0x190e10)
    #26 0x558c3cfa2735 in boost::archive::text_iarchive& boost::archive::detail::interface_iarchive<boost::archive::text_iarchive>::operator>><myProg::NeuralNetwork>(myProg::NeuralNetwork&) /home/martin/myProg/external_dependencies/boost/boost/archive/detail/interface_iarchive.hpp:68
    #27 0x558c3cf83a7d in myProg::NeuralNetwork::NeuralNetwork(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) /home/martin/myProg/src/Network/NeuralNetwork.cpp:32
    #28 0x558c3cf74953 in main /home/martin/myProg/src/examples/myScript_1_2.cpp:119
    #29 0x7f4dca1aa09a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)

Indirect leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x558c3cf36550 in operator new(unsigned long) (/home/martin/myProg/build/bin/examples/myScript_1_2+0x11f550)                                                                         
    #1 0x558c3cf7ca4e in __gnu_cxx::new_allocator<double>::allocate(unsigned long, void const*) /usr/include/c++/8/ext/new_allocator.h:111
    #2 0x558c3cf7b6d8 in std::allocator_traits<std::allocator<double> >::allocate(std::allocator<double>&, unsigned long) /usr/include/c++/8/bits/alloc_traits.h:436
    #3 0x558c3cf79e2f in std::_Vector_base<double, std::allocator<double> >::_M_allocate(unsigned long) /usr/include/c++/8/bits/stl_vector.h:296
    #4 0x558c3cfe0862 in double* std::vector<double, std::allocator<double> >::_M_allocate_and_copy<std::move_iterator<double*> >(unsigned long, std::move_iterator<double*>, std::move_iterator<double*>) /usr/include/c++/8/bits/stl_vector.h:1398
    #5 0x558c3cfdd171 in std::vector<double, std::allocator<double> >::reserve(unsigned long) /usr/include/c++/8/bits/vector.tcc:74
    #6 0x558c3cfd94b9 in void boost::serialization::load<boost::archive::text_iarchive, double, std::allocator<double> >(boost::archive::text_iarchive&, std::vector<double, std::allocator<double> >&, unsigned int, mpl_::bool_<false>) /home/martin/myProg/external_dependencies/boost/boost/serialization/vector.hpp:88
    #7 0x558c3cfd5926 in void boost::serialization::load<boost::archive::text_iarchive, double, std::allocator<double> >(boost::archive::text_iarchive&, std::vector<double, std::allocator<double> >&, unsigned int) /home/martin/myProg/external_dependencies/boost/boost/serialization/vector.hpp:165
    #8 0x558c3cfd377b in boost::serialization::free_loader<boost::archive::text_iarchive, std::vector<double, std::allocator<double> > >::invoke(boost::archive::text_iarchive&, std::vector<double, std::allocator<double> >&, unsigned int) /home/martin/myProg/external_dependencies/boost/boost/serialization/split_free.hpp:58
    #9 0x558c3cfd1ee4 in void boost::serialization::split_free<boost::archive::text_iarchive, std::vector<double, std::allocator<double> > >(boost::archive::text_iarchive&, std::vector<double, std::allocator<double> >&, unsigned int) /home/martin/myProg/external_dependencies/boost/boost/serialization/split_free.hpp:74
    #10 0x558c3cfd08f6 in void boost::serialization::serialize<boost::archive::text_iarchive, double, std::allocator<double> >(boost::archive::text_iarchive&, std::vector<double, std::allocator<double> >&, unsigned int) /home/martin/myProg/external_dependencies/boost/boost/serialization/vector.hpp:176
    #11 0x558c3cfcef4b in void boost::serialization::serialize_adl<boost::archive::text_iarchive, std::vector<double, std::allocator<double> > >(boost::archive::text_iarchive&, std::vector<double, std::allocator<double> >&, unsigned int) /home/martin/myProg/external_dependencies/boost/boost/serialization/serialization.hpp:126
    #12 0x558c3cfcd6a5 in boost::archive::detail::iserializer<boost::archive::text_iarchive, std::vector<double, std::allocator<double> > >::load_object_data(boost::archive::detail::basic_iarchive&, void*, unsigned int) const /home/martin/myProg/external_dependencies/boost/boost/archive/detail/iserializer.hpp:187
    #13 0x558c3d102bae in boost::archive::detail::basic_iarchive_impl::load_object(boost::archive::detail::basic_iarchive&, void*, boost::archive::detail::basic_iserializer const&) (/home/martin/myProg/build/bin/examples/myScript_1_2+0x2ebbae)
    #14 0x558c3d101c90 in boost::archive::detail::basic_iarchive::load_object(void*, boost::archive::detail::basic_iserializer const&) libs/serialization/src/basic_iarchive.cpp:560
    #15 0x558c3cfcbcfc in void boost::archive::detail::load_non_pointer_type<boost::archive::text_iarchive>::load_standard::invoke<std::vector<double, std::allocator<double> > >(boost::archive::text_iarchive&, std::vector<double, std::allocator<double> > const&) /home/martin/myProg/external_dependencies/boost/boost/archive/detail/iserializer.hpp:409
    #16 0x558c3cfc9fb2 in void boost::archive::detail::load_non_pointer_type<boost::archive::text_iarchive>::load_conditional::invoke<std::vector<double, std::allocator<double> > >(boost::archive::text_iarchive&, std::vector<double, std::allocator<double> >&) /home/martin/myProg/external_dependencies/boost/boost/archive/detail/iserializer.hpp:422
    #17 0x558c3cfc88ac in void boost::archive::detail::load_non_pointer_type<boost::archive::text_iarchive>::invoke<std::vector<double, std::allocator<double> > >(boost::archive::text_iarchive&, std::vector<double, std::allocator<double> >&) /home/martin/myProg/external_dependencies/boost/boost/archive/detail/iserializer.hpp:461
    #18 0x558c3cfc7fee in void boost::archive::load<boost::archive::text_iarchive, std::vector<double, std::allocator<double> > >(boost::archive::text_iarchive&, std::vector<double, std::allocator<double> >&) /home/martin/myProg/external_dependencies/boost/boost/archive/detail/iserializer.hpp:624
    #19 0x558c3cfc7961 in void boost::archive::detail::common_iarchive<boost::archive::text_iarchive>::load_override<std::vector<double, std::allocator<double> > >(std::vector<double, std::allocator<double> >&) /home/martin/myProg/external_dependencies/boost/boost/archive/detail/common_iarchive.hpp:67
    #20 0x558c3cfc7506 in void boost::archive::basic_text_iarchive<boost::archive::text_iarchive>::load_override<std::vector<double, std::allocator<double> > >(std::vector<double, std::allocator<double> >&) /home/martin/myProg/external_dependencies/boost/boost/archive/basic_text_iarchive.hpp:70
    #21 0x558c3cfc6ede in void boost::archive::text_iarchive_impl<boost::archive::text_iarchive>::load_override<std::vector<double, std::allocator<double> > >(std::vector<double, std::allocator<double> >&) /home/martin/myProg/external_dependencies/boost/boost/archive/text_iarchive.hpp:82
    #22 0x558c3cfc68d5 in boost::archive::text_iarchive& boost::archive::detail::interface_iarchive<boost::archive::text_iarchive>::operator>><std::vector<double, std::allocator<double> > >(std::vector<double, std::allocator<double> >&) /home/martin/myProg/external_dependencies/boost/boost/archive/detail/interface_iarchive.hpp:68
    #23 0x558c3cfc5c9d in boost::archive::text_iarchive& boost::archive::detail::interface_iarchive<boost::archive::text_iarchive>::operator&<std::vector<double, std::allocator<double> > >(std::vector<double, std::allocator<double> >&) /home/martin/myProg/external_dependencies/boost/boost/archive/detail/interface_iarchive.hpp:75
    #24 0x558c3d0cc359 in void NormalizationStrategy::access::serialize<boost::archive::text_iarchive>(boost::archive::text_iarchive&, NormalizationStrategy&, unsigned int) /home/martin/myProg/src/NormalizationStrategy/NormalizationStrategySerialization.h:22
    #25 0x558c3d0cc1bc in void boost::serialization::serialize<boost::archive::text_iarchive>(boost::archive::text_iarchive&, NormalizationStrategy&, unsigned int) /home/martin/myProg/src/NormalizationStrategy/NormalizationStrategySerialization.h:49
    #26 0x558c3d0cbe24 in void boost::serialization::serialize_adl<boost::archive::text_iarchive, NormalizationStrategy>(boost::archive::text_iarchive&, NormalizationStrategy&, unsigned int) /home/martin/myProg/external_dependencies/boost/boost/serialization/serialization.hpp:126
    #27 0x558c3d0cb9b7 in boost::archive::detail::iserializer<boost::archive::text_iarchive, NormalizationStrategy>::load_object_data(boost::archive::detail::basic_iarchive&, void*, unsigned int) const /home/martin/myProg/external_dependencies/boost/boost/archive/detail/iserializer.hpp:187
    #28 0x558c3d102bae in boost::archive::detail::basic_iarchive_impl::load_object(boost::archive::detail::basic_iarchive&, void*, boost::archive::detail::basic_iserializer const&) (/home/martin/myProg/build/bin/examples/myScript_1_2+0x2ebbae)
    #29 0x558c3d101c90 in boost::archive::detail::basic_iarchive::load_object(void*, boost::archive::detail::basic_iserializer const&) libs/serialization/src/basic_iarchive.cpp:560

SUMMARY: AddressSanitizer: 48 byte(s) leaked in 2 allocation(s).

Я никогда не встречал эту ошибку, и я совершенно сбит с толку, так какэто должно происходить с указателями, как описано в учебнике .Но мои участвующие классы выглядят так:

NormalizationStrategy.h

#include <limits>
#include <vector>

/**
 *
 */
class NormalizationStrategy {
protected:

    /**
     * Maximum (index 0) and minimum (index 1) input value
     */
    std::vector<double> max_min_inp_val;

public:

    /**
     *
     */
    struct access;

    /**
     *
     * @param n
     * @param max
     * @param min
     * @return
     */
    virtual double normalize(double n,
                             double max,
                             double min) = 0;

    /**
     *
     * @param n
     * @param max
     * @param min
     * @return
     */
    virtual double de_normalize(double n) = 0;

    /**
     *
     * @return
     */
    double get_max_value();

    /**
     *
     * @return
     */
    double get_min_value();
};

/**
 *
 */
class DoubleUnitStrategy : public NormalizationStrategy {
public:

    /**
     *
     */
    struct access;

    /**
     *
     */
    DoubleUnitStrategy();

    ~DoubleUnitStrategy();

    /**
     * Normalizes the input value to the interval [-1,1]
     *
     * @param n
     * @param max
     * @param min
     * @return
     */
    double normalize(double n,
                     double max,
                     double min) override;

    /**
     *
     * @param n
     * @return
     */
    double de_normalize(double n) override;
};

NormalizationStrategy.cpp

#include <cmath>
#include <stdexcept>
#include <boost/serialization/export.hpp>

#include "NormalizationStrategy.h"
#include "NormalizationStrategySerialization.h"
#include "exceptions.h"

BOOST_CLASS_EXPORT_IMPLEMENT(NormalizationStrategy)
BOOST_CLASS_EXPORT_IMPLEMENT(DoubleUnitStrategy)

double NormalizationStrategy::get_max_value() {
    return this->max_min_inp_val.at(0);
}

double NormalizationStrategy::get_min_value() {
    return this->max_min_inp_val.at(1);
}

DoubleUnitStrategy::DoubleUnitStrategy() {}

DoubleUnitStrategy::~DoubleUnitStrategy() {}

double DoubleUnitStrategy::normalize(double n,
                                     double max,
                                     double min) {
    if (this->max_min_inp_val.empty()) {
        this->max_min_inp_val.emplace_back(max);
        this->max_min_inp_val.emplace_back(min);
    } else {
        this->max_min_inp_val.at(0) = max;
        this->max_min_inp_val.at(1) = min;
    }

    return 2 * (n - min) / (max - min) - 1;
}

double DoubleUnitStrategy::de_normalize(double n) {
    if (this->max_min_inp_val.empty()) {
        THROW_RUNTIME_ERROR("Data were not normalized, so de-normalization cannot progress!");
    }

    return 0.5 * ((1 + n) * (this->get_max_value() - this->get_min_value())) + this->get_min_value();
}

NormalizationStrategySerialization.h

#include <boost/serialization/base_object.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/vector.hpp>

#include "NormalizationStrategy.h"

BOOST_SERIALIZATION_ASSUME_ABSTRACT(NormalizationStrategy)
BOOST_CLASS_EXPORT_KEY(NormalizationStrategy)
BOOST_CLASS_EXPORT_KEY(DoubleUnitStrategy)

struct NormalizationStrategy::access {
    template<class Archive>
    static void serialize(Archive& ar,
                          NormalizationStrategy& ns,
                          const unsigned int version) {
        ar & ns.max_min_inp_val;
    }
};

struct DoubleUnitStrategy::access {
    template<class Archive>
    static void serialize(Archive& ar,
                          DoubleUnitStrategy& s,
                          const unsigned int version) {
        ar & boost::serialization::base_object<NormalizationStrategy>(s);
    }
};

namespace boost {
    namespace serialization {

        /**
         * Serialization function
         * @tparam Archive Boost library template
         * @param ar Boost parameter - filled automatically during serialization!
         * @param ns NormalizationStrategy instance
         * @param version Boost parameter - filled automatically during serialization!
         */
        template<class Archive>
        void serialize(Archive& ar,
                       NormalizationStrategy& ns,
                       const unsigned int version) {
            NormalizationStrategy::access::serialize(ar,
                                                     ns,
                                                     version);
        }

        /**
         * Serialization function
         * @tparam Archive Boost library template
         * @param ar Boost parameter - filled automatically during serialization!
         * @param s DoubleUnitStrategy instance
         * @param version Boost parameter - filled automatically during serialization!
         */
        template<class Archive>
        void serialize(Archive& ar,
                       DoubleUnitStrategy& s,
                       const unsigned int version) {
            DoubleUnitStrategy::access::serialize(ar,
                                                  s,
                                                  version);
        }
    } // namespace serialization
} // namespace boost

Мы можем видеть, что единственной сериализованной переменной является max_min_inp_val, которая имеет тип std::vector<double>.Итак, что вызывает утечку памяти здесь?

...