【发布时间】:2016-02-04 14:49:45
【问题描述】:
我不知道我如何/为什么不断遇到分段错误。我的代码在 5 分钟前运行良好。我根本没有更改现有代码,只是添加了更多功能。我可以很好地进入 addName 函数,并且在我尝试将新对象推送到列表之前一直工作得很好。早些时候我输入“添加名称乔希戴维斯”,它就像一个魅力,现在我每次都会遇到一个段错误。我做错了什么???
#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;
}
}
【问题讨论】:
-
经过进一步的实验,我发现我在尝试调用构造函数时遇到了分段错误。现在我更加困惑了。有人可以帮我弄清楚发生了什么吗?
-
好的,我发现了问题,只是不知道如何解决。每当我尝试将配偶迭代器的名称成员初始化为构造函数中的默认值时,都会出现段错误。如果我为一个对象设置一个迭代器,然后将它设置为配偶迭代器,它就可以工作。但是,如果我尝试打印出配偶而不先这样做,它会给我另一个段错误。我该如何解决这个问题?
-
您的
spouse迭代器从未初始化,因此它只是一个悬空迭代器。 -
spouse真的应该是Contact*。那可以是nullptr,而且你不应该假设任何关于存储配偶的数据结构。
标签: c++ list stl segmentation-fault