2015-11-04 30 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不引用任何有效的對象。