在此运算符的重载中由std :: ostream :: sentry引起的Segfault

时间:2013-08-20 02:05:59

标签: c++ operator-overloading ostream

我的目标是重载<<运算符,以便Param类的对象适当地打印到标准输出。

Param类在globals.hglobals.cpp文件中定义。在这些文件下面,有一个main.cpp测试程序。此外,还有3个文本输入文件myparam__lbmyparam__midmyparam_ub。将所有这些文件放在同一目录中,这是真实案例的缩小版本。

以下是真实案例的回溯:

#0  0x00007ffff772811e in std::ostream::sentry::sentry(std::ostream&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1  0x00007ffff7728829 in std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2  0x00007ffff7728c0f in std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x0000000000450d32 in initSimulation5 () at ../simulation5.cpp:809
#4  0x000000000042c853 in Policy::Policy (this=0x7fffffffb090) at ../globals_mode.cpp:183
#5  0x00000000004325c4 in readPoliciesFromScript (policies=..., filename=...) at ../globals_utilities.cpp:321
#6  0x0000000000436280 in main (argc=1, argv=0x7fffffffe0d8) at ../main.cpp:122

此代码在另一台计算机上正常运行,但在当前计算机上,它是段错误的。 (两台机器都是64位Ubuntu,但是内核不同,Ubuntu版本等等。)

问题:我的重载<<运算符代码出了什么问题?

globals.h

//globals.h
/* Initialize a Param object with the base file path to the
 * text files containing the low, mid, and high estimates.
 * If the low, mid, and high estimates are, respectively,
 * stored in files
 *
 *    ./input/myparam__lb
 *    ./input/myparam__mid
 *    ./input/myparam__ub
 *
 * then the base file path should be "./input/myparam". 
 */
class Param {
public:
    Param(string baseFilePath, const int size);

    /*! Set Param to its low estimates */
    void setLevelLow();

    /*! Set Param to its mid estimates */
    void setLevelMid();

    /*! Set Param to its high estimates */
    void setLevelHigh();

    /*! Display range of Param values using an ostream */
    friend ostream& operator<< (ostream &out, Param &cParam);

    /*
     * The overloaded operators below allow a Param object to be passed
     * to a function as a (const|nonconst) std::vector<double>& and
     * return a reference to the appropriate set of values based on
     * whether the Param object is set to its low, mid, or high
     * estimates.
     */

    operator std::vector<double>& () {
        if( level < 0 ) return lb;
        if( level > 0 ) return ub;
        return mid;
    }

    operator const std::vector<double>& () const {
        if( level < 0 ) return lb;
        if( level > 0 ) return ub;
        return mid;
    }

private:
    int level;

    std::vector<double> lb;
    std::vector<double> mid;
    std::vector<double> ub;

    void readRatesFromFile(std::vector<double>& x, const string filePath, const int size);

};

globals.cpp

void Param::setLevelLow() { level = -1; }

void Param::setLevelMid() { level = 0; }

void Param::setLevelHigh() { level = 1; }

ostream& operator<< (ostream &out, Param &cParam) {

    /* obtain correct level of parameter */
    vector<double> *pParam;
    switch(cParam.level) {
    case -1:
        pParam = &(cParam.lb);
        out << "-";
        break;
    case 0:
        pParam = &(cParam.mid);
        out << "0";
        break;
    case 1:
        pParam = &(cParam.ub);
        out << "+";
        break;
    default:
        std::cerr << "level=" << cParam.level << " when calling <<(ostream&,Param&)";
            exit(1);
            break;
    }

    /* obtain value(s) of parameter */
    streamsize pre = cout.precision();
    cout.precision(5);
    out << " Value = ";
    double smallest, largest;
    smallest = *min_element(pParam->begin(), pParam->end());
    largest  = *max_element(pParam->begin(), pParam->end());
    if(smallest==largest) {
        out << smallest;
    } else {
        out << "[" << fixed << smallest << ", " <<
                      fixed << largest << "]";
    }
    cout.precision(pre);
}

Param::Param(string baseFilePath, const int size) {

    /* Read lower-bound values from file */
    readRatesFromFile(lb, baseFilePath+"__lb", size);

    /* Read midpoint estimate values from file */
    readRatesFromFile(mid, baseFilePath+"__mid", size);

    /* Read upper-bound values from file */
    readRatesFromFile(ub, baseFilePath+"__ub", size);

    /* by default use midpoint estimate */
    setLevelMid();
}

void Param::readRatesFromFile(std::vector<double>& x, const string filePath, const int size) {

    char line[100];

    x.clear();
    x.resize(size,0.0);

    fstream f_in(filePath.c_str(), ios::in);
    if(f_in.fail()) {
        cerr << "ERROR: Param::param() failed to open file \"" <<
                filePath.c_str() << "\".  Exiting...\n";
        exit(1);
    }
    for(int i=0; i<size; ++i) {
        f_in.getline(line,100);
        x[i]=strtod(line,NULL);
    }
    f_in.close();
}

的main.cpp

//main.cpp
#include <iostream>
#include "globals.h"
int main(int argc, char** argv) {
    Param d("./myparam",3);
    std::cout << d << "\n";
    return 0;
}

myparam__lb

0.13
0.24
0.45

myparam__mid

0.29
0.39
0.56

myparam__ub

0.50
0.61
0.72

1 个答案:

答案 0 :(得分:2)

函数ostream& operator<< (ostream &out, Param &cParam)需要一个return语句。添加return out;后,一切都很顺利。