程序意外退出
Posted
技术标签:
【中文标题】程序意外退出【英文标题】:Program exits unexpectedly 【发布时间】:2021-07-27 06:30:07 【问题描述】:我正在尝试制作一个从文件中获取所有数据的程序,然后用户可以决定向文件中添加更多课程、删除特定课程或在文件中搜索特定课程。我确信还有比我所要求的更多的问题。
在 createNode 函数中,用户应该输入有关课程的所有信息,但在用户输入课程名称后程序关闭。我对编码比较陌生,我曾尝试查找此问题的解决方案,但找不到任何东西。
#include<iostream>
#include<string>
#include<fstream>
#include<cstdlib>
using namespace std;
enum week Mon,Tue,Wed,Thu,Fri;
struct courseInfo
string courseName, CourseID, times[5], building, roomNum;
week day[5];
course;
struct NodeType
courseInfo *data;
NodeType *next;
;
//Function that displays all the courses that are in the file including the courses that are added by the user
//Pre: User inputs the correct file name for the file that has their course information
//Post: Outputs all of the classes in the file for the user to see
void displayAllCourses(string fileName);
//Function that takes a user input course ID and displays that course info
//Pre: The user inputs a valid course ID
//Post: The class the user searched for is displayed
void searchCourse(string fileName);
//Function that allows the user to add another class to the file
//Pre: user adds the information in the way they are prompted
//Post:
void addCourse(string fileName);
// Create and return a new node.
// Pre: None
// Post: Returns a pointer to NodeType with all of the data filled in by user
NodeType *CreateNode();
// Add a given node to a list in a sorted position.
// Pre: listPtr set to a valid list, or nullptr
// newNodePtr assigned to a valid node with valid component value
// Post: listPtr is updated with nodePtr included in the sorted position
void AddNode(string fileName, NodeType *&listPtr, NodeType *newNodePtr);
int main()
NodeType *headPtr; // Always points to the first node in the list
NodeType *lastPtr; // Always points to the last node in the list
NodeType *currPtr; // Working pointer. Points to whatever node it needs to
NodeType *newNodePtr; // Points to a newly created node
string fileName; //Variable for the name of the file the user would like to open
cout << "Please enter the name of the file you would like to open: " << endl;//Prompts the user for the name of the file they would like to open
getline(cin, fileName); //User inputs the file name they want to open
char answer;
while(1) //Loop That repeats until the user inputs that they want to exit
//prompt the user for what action they would like to do
cout<<"Type D to display all your courses"<<endl;
cout<<"Type S to search for a specific course"<<endl;
cout<<"Type A to add another course"<<endl;
cout<<"Type E to exit the program"<<endl;
cout<<"What would you like to do: ";
cin >> answer;
cout<<endl;
//Compares the users choice to the case and executes the code for that case
switch(answer)
case 'D':
displayAllCourses(fileName); //Function call to display all the courses in the file
break;
case 'S':
searchCourse(fileName); //Function call to search for a user defined course by ID
break;
case 'A':
CreateNode();
//AddNode(fileName, headPtr, newNodePtr); //Function call to add another course to the file
break;
default:
exit(0);
NodeType *CreateNode()
NodeType *newNodePtr; // Pointer for new node
newNodePtr = new NodeType;
string day;
cout << "Please enter the Course name: " << endl;
cin >> newNodePtr->data->courseName;
cout << "Please enter Course ID: " << endl;
cin >> newNodePtr->data->CourseID;
cout << "Please enter the day of the course: " << endl;
cin >> day;
cout << "Please enter the time time of the course: " << endl;
getline(cin, newNodePtr->data->times[0]);
cout << "Please enter the building name: " << endl;
getline(cin, newNodePtr->data->building);
cout << "Please enter the room number: " << endl;
getline(cin, newNodePtr->data->roomNum);
if(day=="Monday")
newNodePtr->data->day[0] = Mon;
else if(day=="Tuesday")
newNodePtr->data->day[0] = Tue;
else if(day=="Wednesday")
newNodePtr->data->day[0] = Wed;
else if(day=="Thursday")
newNodePtr->data->day[0] = Thu;
else if(day=="Friday")
newNodePtr->data->day[0] = Fri;
newNodePtr->next = nullptr;
return newNodePtr;
void AddNode(string fileName, NodeType *&listPtr, NodeType *newNodePtr)
NodeType *currPtr = listPtr; // Points to current node in list
NodeType *prevPtr = nullptr; // Points to node before the currPtr
// 1 - Find position in list to add newNodePtr
// Loop while not at end of list and new node value is greater than currPtr value to find sorted location
while ((currPtr != nullptr) &&
(newNodePtr->data->courseName.at(0) > currPtr->data->courseName.at(0)))
// cout << currPtr->component << " "; // Echo node be traversed for debugging purposes
prevPtr = currPtr;
currPtr = currPtr->next;
cout << endl;
// 2 - Insert node
if ((prevPtr == nullptr) && (currPtr == nullptr)) // Pointers never moved, so first/only node
listPtr = newNodePtr; // Set listPtr to new (only) node
else if (prevPtr == nullptr) // prevPtr never moved, so need to add to beginning of list
newNodePtr->next = listPtr; // Point newNodePtr->next to current beginning of list
listPtr = newNodePtr; // Make newNodePtr new first node in list
else if (currPtr == nullptr)
prevPtr->next = newNodePtr; // prevPtr already pointing at last node, so add newPointer as new last node
else
newNodePtr->next = currPtr; // Point newNodePtr->next to currPtr
prevPtr->next = newNodePtr; // Update prevPtr->next to insert newNodePTr in list
fstream file;
file.open(fileName += ".txt", fstream::app); //Adds the new course the the course list in the file
if(!file)
cout<<"Unable to open file!";
exit(1);
cout<<newNodePtr<<endl;
file<<newNodePtr;
file.close();
void displayAllCourses(string fileName)
ifstream file;
file.open(fileName += ".txt"); //Opens the user specified file
if(!file)
cout<<"Unable to open file!"; //Tells the user that the file could not open
exit(1);
int counter=1;
string fileInfo; //String to hold the file information
while(getline(file, fileInfo)) //Loop to display everything in the file
cout<<counter<<": "<<fileInfo<<endl;
counter++;
cout<<endl;
file.close();
void searchCourse(string fileName)
string courseName; //Variable to hold the ID that the user wants to search for
cout<<"Enter the course name: " << endl; //Prompt the user for the ID of the course
cin>>courseName; //User inputs the ID for the course
ifstream file;
file.open(fileName += ".txt"); //Open user specified file
if(!file)
cout<<"Unable to open file!";
exit(1);
string line;
while( getline(file, line ))
size_t pos = line.find(courseName);
if ( pos != string::npos)
cout << line << endl;
cout<<endl;
file.close();
【问题讨论】:
我的建议是使用类似于 Visual Studio 中的调试器来查找崩溃的地方。 标题注释:如果程序按预期退出,你还会问问题吗?由于答案几乎肯定是“No[,]”,因此标题不包含任何信息。一个好的标题将使问题更容易找到并帮助未来有类似问题的提问者。 【参考方案1】:在CreateNode()
中,当您调用new NodeType
时,您正在创建一个新的NodeType
对象,但NodeType
没有实现构造函数,因此它的data
和next
成员保留未初始化。您稍后将nullptr
分配给newNodePtr->next
,但您从未分配newNodePtr->data
指向任何地方。因此,当您尝试将用户的输入读入newNodePtr->data->courseName
时,newNodePtr->data
并未指向有效的courseInfo
对象,因此您会遇到未定义的行为,这会使您的进程崩溃。
你需要为newNodePtr->data
构造一个courseInfo
对象指向,例如:
NodeType *newNodePtr;
newNodePtr = new NodeType;
newNodePtr->data = new courseInfo; // <-- add this!
但是,您应该将该初始化移动到 NodeType
的构造函数中,例如:
struct NodeType
courseInfo *data;
NodeType *next;
NodeType() : data(new courseInfo), next(nullptr)
;
更好的选择是将data
成员更改为实际的courseInfo
对象而不是courseInfo*
指针,例如:
struct NodeType
courseInfo data;
NodeType *next = nullptr;
;
【讨论】:
非常感谢您,我按照您的建议做了,而且效果很好。即使解决方案如此简单,我也坚持了很长时间。 @SwiftTurtle 链表对于初学者来说并不容易理解。我们收到很多与 SO 上的链表相关的问题。你真的应该改用std::list<courseInfo>
。当然不要在现代编码中手动使用new
/delete
。最好根本不使用指针,或者至少使用std::unique_ptr
/std::shared_ptr
来管理它们(虽然,在链接列表中使用unique_ptr
是not a good idea 没有a workaround)。以上是关于程序意外退出的主要内容,如果未能解决你的问题,请参考以下文章
如何解决 J2ME 中的“应用程序因内存不足而意外退出”错误