分段错误将对象推送到列表上

时间:2015-11-04 07:43:13

标签: c++ list stl segmentation-fault

我不知道如何/为什么我一直会遇到分段错误。我的代码在5分钟前工作正常。我根本没有更改现有代码,只添加了更多功能。我可以很好地进入addName函数,并且在我尝试将新对象推入列表之前一直运行良好。早些时候我正在进入“添加名字Josh Davis”,它的工作就像一个魅力,现在我每次都会遇到一个段故障。我做错了什么????

#include <iostream>
#include <string>
#include <list>
#include <sstream>
using namespace std;

// class declaration
class Contact
{
    private:
        // member declarations
    string firstname, lastname, name, name_sort, uid, address, city, state, zip, birthdate, wedding_date, death_date;
    list<Contact>::iterator spouse;
    list<Contact*> children;
public:
    // constructor
    Contact(string nm, string f_nm, string l_nm, int IDcount)
    {
        // stream declaration for concatenation
        stringstream s_strm;

        firstname = f_nm;
        lastname = l_nm;
        name = f_nm + " " + l_nm;
        name_sort = nm;
        spouse->name = "NONE_LISTED";
        address = "NONE_LISTED";
        city = "NONE_LISTED";
        state = "NONE_LISTED";
        zip = "NONE_LISTED";
        birthdate = "NONE_LISTED";
        wedding_date = "NONE_LISTED";
        death_date = "NONE_LISTED";

        if (IDcount < 10)
        {
            string ID = "ID00";
            s_strm << ID << IDcount;
            uid = s_strm.str(); 
        }
        else if (IDcount < 100)
        {
            string ID = "ID0";
            s_strm << ID << IDcount;
            uid = s_strm.str();
        }
        else
        {
            string ID = "ID";
            s_strm << ID << IDcount;
            uid = s_strm.str();
        }
    }

    // get functions
    string getFirstname() { return firstname; }
    string getLastname() { return lastname; }
    string getName() { return name; }
    string getNamesort() { return name_sort; }
    string getUid() { return uid; }
};

int main (void)
{
    // list declaration
    list<Contact> address_book;

// variable declarations
ifstream f_in;
string cmd;
int IDcount = 1;

// print out welcome message and menu
cout << "\n\t\tWelcome to Address Book 2.0!\n"
     << "\nAVAILABLE COMMANDS:\n"
         << "\tadd name <name> ==> Add a new name (First Last) to the Address Book\n"
         << "\tadd spouse <uid> <name> ==> Add spouse of <uid> (First Last) to the Address Book\n"
         << "\tadd child <uid> <name> ==> Add a child of <uid> (First Last) to the Address Book\n"
         << "\tadd address1 <uid> <address> ==> Add/change the address for <uid>\n"
         << "\tadd city <uid> <city> ==> Add/change the city for <uid>\n"
         << "\tadd state <uid> <state> ==> Add/change the state for <uid>\n"
         << "\tadd zip <uid> <zipcode> ==> Add/change the zipcode for <uid>\n"
         << "\tadd date_birth <uid> <ddmmyyyy> ==> Add/change the birthday for <uid>\n"
         << "\tadd date_wedding <uid> <ddmmyyyy> ==> Add/change the wedding day for <uid>\n"
         << "\tadd date_death <uid> <ddmmyyyy> ==> Add/change the date of death for <uid>\n"
         << "\tsearch <name> ==> searches for name (First Last) and returns the <uid>, if found\n"
         << "\tprint all ==> Prints a list of ALL of the names in the Address Book with their <uid> <name>\n"
         << "\tprint <uid> ==> Prints all of the fields for <uid>\n"
         << "\tfile ==> user is prompted for a filename that contains correctly formatted commands\n"
         << "\t               --- the file must be in CSV format with one full command per line\n"
         << "\tquit ==> processing complete\n\n"
         << "cmd> ";


// obtain command, call appropriate function, loop if desired
do
{
    getline(cin, cmd);

    if (cmd.compare(0, 9, "add name ") == 0 || cmd.compare(0, 9, "ADD NAME ") == 0)
    {
        addName(address_book, cmd, IDcount);
        cout << "\ncmd> ";
    }

    else
    {
        cout << "ERROR: Invalid input. Either you entered an unrecognized command or used an incorrect number of parameters." << endl;
        cout << "\ncmd> ";
    }

} while (cmd != "quit" && cmd != "QUIT");

return 0;
}

void addName(list<Contact>& address_book, string cmd, int& IDcount)
{
// variable declarations
string f_name, l_name, nm;
bool duplicate = false;
list<Contact>::iterator it;

if (cmd.length() > 9) // ensure that there is another parameter after "add name "
{
    cmd.erase(0, 9); // erase the command portion of the line input by the user, leaving only the name
    // http://www.cplusplus.com/reference/string/string/substr/
    size_t pos = cmd.find(" "); // find the position of the space between the first and last name
    l_name = cmd.substr(pos + 1); // get the last name and assign it to the variable

    cmd.erase(pos, -1); // erase the last name (http://www.cplusplus.com/reference/string/string/npos/)
    f_name = cmd; // assign the first name to the variable
    nm = l_name + " " + f_name; // assign last name, first name to a variable for sorting

    // search for duplicates if the list is not empty
    if (IDcount != 1)
    {
        for (it = address_book.begin(); it != address_book.end(); ++it)
        {
            if (it->getNamesort() == nm) // if duplicate is found, output error message and update the bool so that it will not be added to the list
            {
                cout << "DUPLICATE: " << it->getName() << " UID: " << it->getUid() << endl;
                duplicate = true;
            }
        }
    }

    if (duplicate == false) // no duplicates found
    {
        address_book.push_front(Contact(nm, f_name, l_name, IDcount)); // create a new object in Contact class and add to the beginning of the list
        // NEVER MAKE IT PAST HERE - SEGMENTATION FAULT
        IDcount++;
        it = address_book.begin();
        cout << "ADDED: " << it->getName() << " UID: " << it->getUid() << endl;
        address_book.sort(comp_by_name_sort); // sort the entries in the list alphabetically by last name, then first name
    }
}

else // no input after "add name "
{
    cout << "ERROR: Not enough command parameters." << endl;
}
}

1 个答案:

答案 0 :(得分:2)

    list<Contact>::iterator spouse; <- iterator points to nothing
    list<Contact*> children;
public:
    // constructor
    Contact(string nm, string f_nm, string l_nm, int IDcount)
    {
        // stream declaration for concatenation
        stringstream s_strm;

        firstname = f_nm;
        lastname = l_nm;
        name = f_nm + " " + l_nm;
        name_sort = nm;
        spouse->name = "NONE_LISTED"; <- act as if spouse points to valid object

我不知道你认为最后一行有什么,但它显然无效。 spouse迭代器不引用任何有效对象。