lundi 16 septembre 2019

Run-time error abuot allocation when overloading operator+ in a class with user-defined literals

I wrote some class that uses literal operators to indicate a measurement error to be used in physical applications. I encountered some run-time errors after I implemented a user-defined literal ""_err, as I have overloaded operator+ between two objects, Double and Error.

A class named Double holds a double and an Error. Everything is inside a namespace TStat. I have defined a literal ""_err that takes long double as an argument and returns a struct called Error. For instance, 1.3_err.

I defined operator+ to merge a double (or Double) and an Error. Everything is fine, until I do the operation Double+Error (or double+Error) in run-time. The error message is as follows:

example.exe(91424,0x10a5195c0) malloc: *** error for object 0x7fd9e8402b00: pointer being freed was not allocated
example.exe(91424,0x10a5195c0) malloc: *** set a breakpoint in malloc_error_break to debug
Abort trap: 6

I have tried many combinations, like defining the operator+ internally or externally, etc. I have searched similar questions but everything seems fine in the code according to my sources / referrences. A problem about the literal operator part has been asked and answered here, it might be related, so I included the related lines below, as well.

This is the header file, TStat.h:

#ifdef TSTAT_H
#define TSTAT_H

namespace TStat {
    struct Error {
        // ...
    }

    Error operator "" _err(long double err);
    Error operator+ (Error, Error);
    Double operator+ (double, Error);

    class Double {
        // constructors, etc.
        // ...

        friend Double operator+ (Double, Error);            
    }
}

and this is the TStat.cpp file:

#include "TStat.h"

using namespace TStat;

// ...

TStat::Double TStat::operator +(TStat::Double value, TStat::Error err) {
    // ...
    return value;
}

TStat::Error TStat::operator +(TStat::Error err1, TStat::Error err2) {
    TStat::Error err;
    // ...
    return err;
}

TStat::Double TStat::operator +(double mean, TStat::Error err) {
    TStat::Double value;
    // ...
    return value;
}

std::ostream& operator<<(std::ostream& os, const TStat::Double& obj)
{
    os  << obj.mean << " (+"
        << obj.errors.plus << ", "
        << obj.errors.minus << ")";
    return os;
}

TStat::Error TStat::operator"" _err(long double err) {
    TStat::Error error;
    // ...
    return error;
}

I compiled, with the following command in the terminal (I am using MacOS)

g++ -Wall -g -std=c++11 example.cpp TStat.cpp -o example.exe

an example.cpp like this:

#include "TStat.h"

using namespace TStat;

int main() {
    Double a;
    Error b;

    std::cout << a+b << std::endl;

    //   It isn't about operator<< because
    //   It would give the same error
    //   even if I instead tried
    // Double c;
    // c = a+b

    return 0;
}

Aucun commentaire:

Enregistrer un commentaire