-1

次の行でセグメンテーション違反が発生しています。

 employees.push_back(Salesperson(id, fname, lname));

何が原因なのか、まったくわかりません。私がしようとしているのは、テキスト ファイルを読み取り、その情報を各値のゲッターとセッターといくつかの比較演算子だけを持つ単純なクラスに入れ、そのクラスのオブジェクトをリストに入れることだけです。リストに挿入しようとすると、何らかの理由でセグメンテーション違反が発生します。終了イテレータを逆参照しようとしているわけではなく、どのリスト挿入メソッドを使用しても違いはありません。それらはすべて同じことを引き起こします。

int main(int argc, char** argv)
{
    ifstream input;
    input.open("sales.txt");
    string s;
    istringstream ss;

    list<Salesperson> employees;

    while (getline(input, s))
    {
        ss.str(s);

        int year, id, sales;
        string fname, lname;

        ss >> year;
        ss >> id;
        ss >> fname;
        ss >> lname;
        ss >> sales;

        getline(input, s);
        ss.str(s);
        float sale;
        OrderedList<float> ol;

        for (int i = 0; i < sales; i++)
        {
            ss >> sale;
            ol.insert(sale);
        }


        list<Salesperson>::iterator it = find(employees.begin(), employees.end(), Salesperson(id, fname, lname));
        if (it == employees.end()) {
            employees.push_back(Salesperson(id, fname, lname));
            employees.back().setSales(employees.back().getSales() + ol);
        } else {
            it->setSales(it->getSales() + ol);
        }

        cout << it->getSales() << endl;

    }
    input.close();

    return 0;
}

販売員クラス

#ifndef SALESPERSON_H
#define SALESPERSON_H

#include <string>
class Salesperson
{
public:
    //Constructor
    Salesperson(int id, std::string fn, std::string ln)
    {
        employeeID = id;
        fname = fn;
        lname = ln;
    }

    //Gang of Three
    Salesperson(const Salesperson& orig) {*this = orig;}
    ~Salesperson() {}
    void operator=(const Salesperson& orig) 
    {
        employeeID = orig.employeeID;
        fname = orig.fname;
        lname = orig.lname;
        sales = orig.sales;
    }

    //Getters
    int getEmployeeID() {return employeeID;}
    std::string getFname() {return fname;}
    std::string getLname() {return lname;}
    OrderedList<float> getSales() {return sales;}

    //Setters
    void setEmployeeID(int a) {employeeID = a;}
    void setFname(std::string a) {fname = a;}
    void setLname(std::string a) {lname = a;}
    void setSales(OrderedList<float>& a) {sales = a;}

    //Operators
    bool operator<(Salesperson s) {return employeeID < s.employeeID;}
    bool operator==(Salesperson s) {return employeeID == s.employeeID;}
private:
    //Fields
    int employeeID;
    std::string fname, lname;
    OrderedList<float> sales;
};

OrderedList cpp

#include "Node.h"

template<class type>
OrderedList<type>::OrderedList(const OrderedList<type>& list)
{
    *this = list;
}

template<class type>
void OrderedList<type>::clear()
{
    for (Node<type>* i = head; i != NULL; head = i)
    {
        i = i->getLink();
        delete head;
    }
    size = 0;
}

template<class type>
void OrderedList<type>::remove(type item)
{
    Node<type>* temp = head, *prev = head;
    for (; temp != NULL; prev = temp, temp = temp->getLink())
        if (item == temp->getData()) break;

    if (temp != NULL)
    {
        if (prev == temp) head = head->getLink();
        else prev->setLink(temp->getLink());
        delete temp;
        size--;
    }
}

template<class type>
void OrderedList<type>::operator=(const OrderedList<type>& list)
{
    clear();
    Node<type>* tail = NULL;
    for (Node<type>* i = list.head; i != NULL; i = i->getLink())
    {
        if (head == NULL)
        {
            head = new Node<type > (i->getData(), NULL);
            tail = head;
        } else
        {
            tail->setLink(new Node<type > (i->getData(), NULL));
            tail = tail->getLink();
        }
    }
    size = list.size;
}

template<class type>
std::ostream& operator<<(std::ostream& out, const OrderedList<type>& list)
{
    out << "[";
    for (Node<type>* i = list.head; i != NULL; i = i->getLink())
    {
        out << i->getData();
        if (i->getLink() != NULL) out << ", ";
    }
    out << "]";

    return out;
}

template<class type>
void OrderedList<type>::insert(type d)
{
    size++;
    Node<type>* item = new Node<type>(d, NULL);

    Node<type> *i = head, *prev = NULL;
    while (i != NULL)
    {
        if (i->getData() >= d) break;
        prev = i;
        i = i->getLink();
    }

    if (prev == NULL)
    {
        item->setLink(head);
        head = item;
    } else {
        prev->setLink(item);
        item->setLink(i);
    }
}

template<class type>
type OrderedList<type>::get(int k) const
{
    if (k <= 0 || k > size) return NULL;

    Node<type>* i = head;
    type data;
    for (int j = 0; j < k; j++)
    {
        data = i->getData();
        i = i->getLink();
    }
    return data;
}

template<class type>
OrderedList<type> OrderedList<type>::kLargest(int k) const
{
    OrderedList list;
    Node<type>* i = head;

    if (k <= 0 || k > size) return list;

    for (int j = 0; j < size-k; j++)
    {
        i = i->getLink();
    }
    for (int j = 0; j < k; j++)
    {
        list.insert(i->getData());
        i = i->getLink();
    }
    return list;
}

template<class type>
OrderedList<type> OrderedList<type>::operator+(const OrderedList& list) const
{
    Node<type>* i = head;
    Node<type>* j = list.head;

    OrderedList newList;
    Node<type>* end;

    for(int k = 0; k < size + list.size; k++)
    {
        if(newList.size == 0 && i->getData() <= j->getData()) {
            newList.head = new Node<type>(i->getData(), NULL);
            end = newList.head;
            i = i->getLink();
            newList.size++;
            continue;
        } else if(newList.size == 0 && i->getData() <= j->getData()) {
            newList.head = new Node<type>(j->getData(), NULL);
            end = newList.head;
            j = j->getLink();
            newList.size++;
            continue;
        }

        if(i == NULL) {
            end->setLink(new Node<type>(j->getData(), NULL));
            end = end->getLink();
            j = j->getLink();
        } else if(j == NULL) {
            end->setLink(new Node<type>(i->getData(), NULL));
            end = end->getLink();
            i = i->getLink();
        } else if(i->getData() <= j->getData()) {
            end->setLink(new Node<type>(i->getData(), NULL));
            end = end->getLink();
            i = i->getLink();
        } else if(i->getData() > j->getData()) {
            end->setLink(new Node<type>(j->getData(), NULL));
            end = end->getLink();
            j = j->getLink();
        }

        newList.size++;
    }

    return newList;
}
4

2 に答える 2

1

Salespersonクラスに何か問題がある可能性があります。おそらく3 つのルールに違反しているか、別の同様の問題があります。そのコードを見なければ、より具体的にすることは困難です。

于 2013-04-17T06:18:20.443 に答える
0

テンプレート クラスの大部分が .cpp ファイルで定義されているのは奇妙です。それOrderedList<>が問題に関係しているかどうかはわかりません。

ただし、コピー ctor:

template<class type>
OrderedList<type>::OrderedList(const OrderedList<type>& list)
{
    *this = list;
}

少なくとも 1 つの問題があるようです。

コピー コンストラクターはオブジェクトの構築を担当するため、初期化子リストで初期化されていないメンバーの状態は明確に定義されていない可能性があります (特にポインターなどの基本型)。コピーの作業を代入演算子に委任しようとしています:

template<class type>
void OrderedList<type>::operator=(const OrderedList<type>& list)
{
    clear();
    Node<type>* tail = NULL;
    for (Node<type>* i = list.head; i != NULL; i = i->getLink())
    {
        if (head == NULL)
        {
            head = new Node<type > (i->getData(), NULL);
            tail = head;
        } else
        {
            tail->setLink(new Node<type > (i->getData(), NULL));
            tail = tail->getLink();
        }
    }
    size = list.size;
}

関数が最初に行うことoperator=()は呼び出しですclear()clear()、メンバーが適切なものに初期化されることに依存してheadいますが、これは構築中のオブジェクトではまだ発生していません (head明らかに生のポインターであるため)。少なくともhead(およびおそらく の他のメンバーの初期化リスト項目が必要ですOrderedList<>:

template<class type>
OrderedList<type>::OrderedList(const OrderedList<type>& list)
    : head(0)
{
    *this = list;
}
于 2013-04-17T07:19:04.077 に答える