mercredi 25 novembre 2020

Core dump error when using an ifstream as parameter

I was working on the Calculator problem provided in Bjarne Stroustrup's book - Programming Principles and Practice Using C++. An exercise stated to modify a class to use an istream as an explicit parameter, to allow input from a file. The code works if I pass cin to the function. Howerver, if I give it an ifstream, the program does what it's supposed to do, then exits with a segmentation fault. Here's the main() function:

#include "std_lib_facilities.h"
#include "token.h"
#include "variable.h"
#include "calculator.h"

//NOTE: The Token_stream works with files, but not fully:
    //it reads from them, does the correct calculations, but then crashes with a a core dump error, double free or corruption (out)
ifstream istr;

Token_stream ts(istr);
Symbol_table st;
void initialize_custom_variables();

int main()
{
    istr.open("input.txt");
    initialize_custom_variables();
    intro_message();
    calculate(ts, st);
    istr.close();
    return 0;
}

void initialize_custom_variables()
{
    st.define_variable("pi", 3.14159, true);
    st.define_variable("e",2.71828 , true);
}

Here are the header files used:

token.h

#pragma once
#include "std_lib_facilities.h"
//Token implementation----------------------------------------------------------
class Token {
public:
    char type;
    double value;
    string name;   // used for a Token of type name

    Token(char ch) :type{ ch }, value{ 0 } {};
    Token(char ch, double val) :type{ ch }, value{ val } {};
    Token(char ch, string n) :type{ ch }, name{ n } {};
};
//-------------------------------------------------------------------------------

//Token_stream implementation----------------------------------------------------
class Token_stream {
public:
    Token_stream(istream& istr);
    Token get();
    void putback(Token t);
    void ignore(char c);

private:
    bool isFull;
    Token buffer;
    istream& istr_p;
};

variable.h

#pragma once
#include "std_lib_facilities.h"

//Variable implementation--------------------------------------------------------
class Variable
{
public:
    std::string name;
    double value;
    bool isConst;

    Variable(std::string st, double v, bool b) : name{ st }, value{ v }, isConst{ b } {}
    Variable(std::string st, double v) : name{ st }, value{ v }, isConst{ false } {}
};

class Symbol_table
{
public:
    double get_value(std::string s);
    void set_value(std::string s, double n); //We all have our daemons, running in the background without us realising it.
    bool is_declared(std::string var);
    double define_variable(std::string var, double val, bool isConst);
    void show_variables();

private:
    vector <Variable> var_table;
};

calculator.h

#pragma once
// forward declarations
//class Token_stream;
//class Symbol_table;
#include "token.h"

//Declarations and Initializations-----------------------------------------------
void calculate(Token_stream& ts, Symbol_table& st);
double statement(Token_stream& ts, Symbol_table& st);
double declaration(Token_stream& ts, Symbol_table& st);
double square_root(Token_stream& ts, Symbol_table& st);
double powerf(Token_stream& ts, Symbol_table& st);
double expression(Token_stream& ts, Symbol_table& st);
double term(Token_stream& ts, Symbol_table& st);
double factorial(Token_stream& ts, Symbol_table& st);
double primary(Token_stream& ts, Symbol_table& st);
double variable(Token_stream& ts, Symbol_table& st);
void intro_message();
void cleanup(Token_stream&);
//-------------------------------------------------------------------------------

Aucun commentaire:

Enregistrer un commentaire