使用stl列表时的神秘段错误

时间:2013-04-17 06:16:42

标签: c++ list segmentation-fault

我在以下一行中遇到了一个段错误:

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

我没有丝毫的线索可能导致它。我所要做的就是读取一个文本文件,将其中的信息放入一个简单的类中,除了每个值的getter和setter以及一些比较运算符,并将该类的对象放入列表中。出于某种原因,任何时候我尝试插入列表,它会段错误。我不是试图取消引用结束迭代器,并且我使用哪个列表插入方法没有区别。所有这些都会导致同样的事情。

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;
}

2 个答案:

答案 0 :(得分:1)

Salesperson类可能有问题。它可能违反了Rule of Three或者有另一个相似的问题。没有看到它的代码就很难更具体。

答案 1 :(得分:0)

奇怪的是,您的OrderedList<>模板类主要在.cpp文件中定义 - 我不知道这是否与您的问题有关。

然而,副本:

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

看起来至少有一个问题。

由于复制构造函数负责构造对象,因此初始化列表中未初始化的成员的状态可能没有很好地定义 - 特别是像指针这样的基类型。您正在尝试将副本的工作委派给赋值运算符:

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;
}