2015-11-04 27 views
-1

我不知道如何/为什么我继续得到分段错误。我的代码在5分钟前工作正常。我根本没有改变现有的代码,只增加了更多的功能。我可以进入addName函数,直到我尝试将新对象推送到列表中为止。早些时候,我进入了“添加名称乔希戴维斯”,它的工作就像一个魅力,现在我每次都得到一个seg错误。我究竟做错了什么????将对象推到列表上的分段错误

#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; 
} 
} 
+0

经过进一步的实验,我发现我在尝试调用构造函数时遇到了分段错误。现在我更加困惑。有人能帮我弄清楚发生了什么事吗? –

+0

好吧,我想出了问题,我只是不知道如何解决它。每当我尝试将配偶迭代器的名称成员初始化为构造函数中的默认值时,我都会遇到seg故障。如果我将一个迭代器设置为一个对象,然后将其设置为配偶迭代器,它将起作用。但是,如果我试图打印出配偶,而不是先做这件事,那会给我带来另一个seg故障。我该如何解决? –

+0

你的'spouse'迭代器永远不会被初始化,所以它只是一个悬而未决的迭代器。 –

回答

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不引用任何有效的对象。