Search code examples
c++segmentation-faultoperatorscoredumpredefine

segmentation fault (core dump) c++


I've been writing code for my class assignment and when I rut it in terminal with g++ command , it gives me segmentation fault. The code is big but first part, when I insert elements of map, it works ( because once it wrote the command and then crushed) and then when it has to cast (this is assignment with Redefinition operators) it crashes. so can someone please help me.

#include <iostream>
#include <map>
#include <algorithm>
#include <string>
#include <typeinfo>
#include "druga_verzija.h"

using namespace std;
//constructor 
Posiljka::Posiljka(){
    m.clear();

}


//how to print my map
ostream&operator<<(ostream&f, Posiljka&p){
    map<string , int>::iterator it;
    it=p.m.begin();
    cout << it->second << "x" << it->first;
    for( it=p.m.begin() ; it != p.m.end() ; ++it){
        cout << " " << it->second << "x" << it->first;
    }
}

//how to insert elements
Posiljka&Posiljka::operator<<(string s){
    if(m.empty()){
        m.insert(pair<string,int>(s,1));
        return *this;
    }
    map<string ,int>::iterator it=m.begin();
    for(; it != m.end() ; ++it){
        if( it->first == s){
            it->second++;
            return *this;
        }
        if( it->first > s){
            m.insert( it, pair<string,int>(s , 1)); 
            return *this;
        }
    }
    if(it == m.end()){
        m.insert(pair<string,int>( s, 1));
        return *this;
    }
}

//how to delete them 
Posiljka&Posiljka::operator>>(string s){
    if(m[s]){
        m[s]=m[s]-1;
        if(!m[s]){
            m.erase(s);
            return *this;
        }
        return *this;
    }
    return *this;
}
//how to make new map that contains two old maps
Posiljka Posiljka::operator|(Posiljka &p){
    Posiljka novi;
    map<string,int>::iterator it;
    for( it = p.m.begin() ; it!= p.m.end() ; ++it)
        novi.m[it->first]=it->second;
    for( it = m.begin(); it != m.end() ; ++it){
        if(novi.m[it->first])
            novi.m[it->first] = novi.m[it->first] + it->second;
        else
            novi.m[it->first] = it->second;
        }
    return novi;
}

//multiply map witn int and make new map
Posiljka Posiljka::operator*(int x){
    map<string , int>::iterator it;
    Posiljka novi;
    for( it=m.begin() ; it!=m.end() ; ++it)
        novi.m[it->first] = it->second * x;
    return novi;
}

//write how much objects map has
Posiljka::operator int(){
    int suma=0;
    map<string , int>::iterator it;
    for( it = m.begin() ; it != m.end() ; ++it)
        suma = suma + it->second;
    return (int)suma;
}
//write maks of one object
int Posiljka::operator+(){
    int maks=0;
    map<string, int>::iterator it;
    for( it = m.begin() ; it != m.end() ; ++it)
        if( it->second > maks)
            maks=it->second;
    return maks;
}

//write min of one object
int Posiljka::operator-(){
    if(m.begin()->second)
        return 0;
    int mini=m.begin()->second;
    map<string, int>::iterator it;
    for( it=m.begin() ; it!=m.end() ; ++it)
        if( it->second < mini)
            mini=it->second;
    return mini;
}
//if there is object s in thios map
bool Posiljka::operator()(string s){
    if(m[s])
        return true;
    else
        return false;
}

my main:

#include <iostream>
#include "druga_verzija.h"
using namespace std;
int main()
{
Posiljka P, Q, R; 
P << "olovka" << "tipkovnica" << "olovka" << "olovka";
cout << P << endl;
P << "olovka" << "monitor" << "tipkovnica" << "gitara";
cout << P << endl;
//1xgitara 1xmonitor 4xolovka 2xtipkovnica
cout << (int)P << endl;
//8
Q = P*2;
cout << Q << endl;
//2xgitara 2xmonitor 8xolovka 4xtipkovnica
R = P | Q;
cout << R << endl;
//3xgitara 3xmonitor 12xolovka 6xtipkovnica
cout << -R << " " << +R << endl;
//3 12
while ( R("olovka") )
R >> "olovka";   
cout << R << endl;
//3xgitara 3xmonitor 6xtipkovnica
R >> "gitara" >> "monitor" >> "tipkovnica" >> "tipkovnica";
cout << R << endl;
//2xgitara 2xmonitor 4xtipkovnica
return 0;
}

my interface:

#include <iostream>
#include <map>
#include <string>
#include <typeinfo>


using namespace std;

class Posiljka
{
private:

map<string,int> m;

public:

Posiljka();
friend ostream&operator<<(ostream&, Posiljka&);
Posiljka&operator<<(string s);
Posiljka&operator>>(string s);
Posiljka operator|(Posiljka &p);
Posiljka operator*(int x);
operator int();
int operator+();
int operator-();
bool operator()(string s);





};

Solution

  • One problem right away is that you are not returning values from a function declared to return values:

    ostream&operator<<(ostream&f, Posiljka&p)
    {
        map<string , int>::iterator it;
        it=p.m.begin();
        cout << it->second << "x" << it->first;
        for( it=p.m.begin() ; it != p.m.end() ; ++it)
        {
            cout << " " << it->second << "x" << it->first;
        }
    
       // Where is the return????
    }
    

    Not returning a value from a function that is declared to return a value is undefined behavior. The function probably should be:

    ostream&operator<<(ostream &f, const Posiljka &p)
    {
        map<string , int>::const_iterator it;
        it=p.m.begin();
        f << it->second << "x" << it->first;
        for( it=p.m.begin() ; it != p.m.end() ; ++it)
        {
            f << " " << it->second << "x" << it->first;
        }
        return f;
    }
    

    1) Your output stream is f, it shouldn't be cout.

    2) You should pass Posiljka by const reference.

    3) Note now we return f.

    This function probably suffers from the same issue:

    Posiljka&Posiljka::operator<<(string s)

    In that function, you do have return statements, but not all paths return a value.