vendredi 22 mai 2015

C++ Pointer being freed was not allocated - possibly an issue with unique_ptr or optimisation

I have encountered a problem with a custom vector-type class. I get a runtime error dynamic_links(3941,0x7fff749a2310) malloc: *** error for object 0x61636f6c65720054: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug

The problem seems to be intermittent and stops occurring whenever I make any small change in the application code (e.g. adding an std::cout in an arbitrary place). The problem also appears and disappears randomly if I make changes to the compiler optimisation options (e.g. if I change from -O3 or -Ofast). For example, a certain code configuration (by configuration I mean introduction of std::couts in an arbitrary places) may work with one optimisation, but produce an error when I use another optimisation. I could not reproduce the problem with the -O2 optimisation flag.

Both the classes and the application codes are quite long and rely on a variety of custom types. However, most of the code associated with the classes are getter and setter functions. Here, I only provide the constructors and the member variables of the classes. The functionality of the getter/setter functions should be apparent from the code.

Unfortunately, I am also having difficulties debugging the code using gdb. I am relying on several external libraries and whenever I use stepping function in gdb I get the following message:

Single stepping until exit from function main,
which has no line number information.

The code fragments are presented below:

template<typename TTimeType, typename TStateSpaceType>
class DSTrajectoryPoint
{

protected:

    TTimeType m_PointTime;
    std::unique_ptr<TStateSpaceType> m_up_StateValue;

public:

    DSTrajectoryPoint()
        {
            m_PointTime = 0;
            m_up_StateValue = nullptr;
        }

    DSTrajectoryPoint(
        TTimeType i_PointTime, const TStateSpaceType& i_StateValue
        ): m_PointTime(i_PointTime),
           m_up_StateValue(
               std::unique_ptr<TStateSpaceType>(
                   new TStateSpaceType(i_StateValue)
                   )
               )
        {}

    DSTrajectoryPoint(
        TTimeType i_PointTime,
        std::unique_ptr<TStateSpaceType> i_up_StateValue
        ): m_PointTime(i_PointTime),
           m_up_StateValue(std::move(i_up_StateValue))
        {}

    DSTrajectoryPoint(
        const DSTrajectoryPoint<TTimeType, TStateSpaceType>&
        i_rc_DSTrajectoryPointInstance
        ): m_PointTime(i_rc_DSTrajectoryPointInstance.returnTime()),
           m_up_StateValue(
               std::unique_ptr<TStateSpaceType>(
                   new TStateSpaceType(
                       i_rc_DSTrajectoryPointInstance.
                       returnStateValue()
                       )
                   )
               )
        {}
};

template<
    typename TTimeType,
    typename TStateSpaceType,
    class TDSTrajectoryPointType
    >
class DSTrajectory
{

protected:

    std::vector<std::unique_ptr<TDSTrajectoryPointType>>
    m_Trajectory;

public:

    DSTrajectory(void)
        {checkPointType();}

    DSTrajectory(
        const DSTrajectory<
        TTimeType,
        TStateSpaceType,
        TDSTrajectoryPointType
        >& i_rc_Trajectory)
        {
            checkPointType();
            for (
                Index InputTrajectoryIndex(0);
                InputTrajectoryIndex <
                    i_rc_Trajectory.returnNumberOfPoints();
                InputTrajectoryIndex++
                )
            {
                m_Trajectory.push_back(
                    std::unique_ptr<TDSTrajectoryPointType>(
                        new TDSTrajectoryPointType(
                            i_rc_Trajectory[InputTrajectoryIndex]
                            )
                        )
                    );
            }
        }
};


int main()
{

    Rn<> Q1(3);
    std::unique_ptr<Rn<>> pQ2(new Rn<>(3));
    DSTrajectoryPoint<Real, Rn<>> B1(10, Q1);
    DSTrajectoryPointCTRn<> B2(10, std::move(pQ2));
    DSTrajectoryPointCTRn<> B3(B2);

    std::unique_ptr<Rn<>> pQ3(new Rn<>(4));

    B1.setState(Q1);
    B1.setState(std::move(pQ3));
    B1.setValue(3, Q1);

    DSTrajectory<
        Real,
        Rn<>,
        DSTrajectoryPointCTRn<>
        > T;

    T.pushBackTrajectoryPoint(B2);
    T.pushBackTrajectoryPoint(B2);
    B2.setTime(20);
    T.pushBackTrajectoryPoint(B2);

    std::unique_ptr<Rn<>> pQ4(new Rn<>(3));
    std::unique_ptr<DSTrajectoryPointCTRn<>>
        pB4(new DSTrajectoryPointCTRn<>(B2));

    T.setPoint(1, 10, Q1);
    T.setPoint(1, 10, std::move(pQ4));
    T.setPoint(1, std::move(pB4));

    std::cout << T.returnNumberOfPoints() << std::endl;
    T.erasePoint(1);
    std::cout << T.returnNumberOfPoints() << std::endl;
    T.erasePoints(PolyIndex{0, 2});
    std::cout << T.returnNumberOfPoints() << std::endl;

    T.emplacePoint(0, 10, Q1);
    T.emplacePoint(0, 4, Q1);
    T.emplacePoint(2, 14, Q1);

    std::unique_ptr<Rn<>> pQ5(new Rn<>(3));
    T.emplacePoint(2, 14, std::move(pQ5));

    std::cout << T.returnNumberOfPoints() << std::endl;

    Rn<> Z1(3);
    std::unique_ptr<Rn<>> pZ2(new Rn<>(3));
    DSTrajectoryPoint<Natural, Rn<>> D1(10, Z1);
    DSTrajectoryPointDTRn<> D2(10, std::move(pZ2));
    DSTrajectoryPointDTRn<> D3(D2);

    DSTrajectory<
        Real,
        Rn<>,
        DSTrajectoryPointCTRn<>
        > T2(T);

    std::cout << T2.returnNumberOfPoints() << std::endl;
    std::cout << T2[0].returnTime() << std::endl;
    std::cout << T2[1].returnTime() << std::endl;

    return 0;

}

Aucun commentaire:

Enregistrer un commentaire