分段故障和指针问题

Seg Fault and Pointer issues

本文关键字:问题 指针 故障 分段      更新时间:2023-10-16

我在课堂上花了几天时间研究这个程序,但我一直遇到seg错误。我可以注释掉我认为导致错误的代码部分,然后我就不再出现错误,但我的打印功能就不起作用了。我明天要拿起c++书来帮忙。

//linkedList.cpp
//Declaration of main and menu functions
//Programmer: Ronnie Warden
//Date: 2.15.15
#include<iostream>
#include "link.h"
using namespace std;
int main()
{
    Node *list = new Node;
    int delNode;
    int findNode;
    int choice = 1;
    list->next = NULL;
    while (choice != 5)
    {
        choice = menu();
        if (choice == 1)
            *list = insertNode(list);
        if (choice == 2)
        {   
            cout << "Enter the ID you wish to delete: ";
            cin >> delNode;
            *list = deleteNode(list, delNode);
        }
        if (choice == 3)
            printNode(list);
        if (choice == 4)
        {
            cout << "Enter the ID you are searching for: ";
            cin >> findNode;
            *list = searchNode(list, findNode);
        }
    if (choice < 1 || choice > 5)
        cout << "Invalid choice! Please try again." << endl;
}
return 0;
}
int menu()
{
    int choice = 1;
         cout << "1. Insert Node" << endl;
         cout << "2. Delete Node" << endl;
         cout << "3. Print List" << endl;
         cout << "4. Search List" << endl;
         cout << "5. Quit" << endl;
         cin >> choice;
return choice;
}

以下部分是抛出seg错误的部分。

//linkFun.cpp
//Declaration of functions used to manage the linked list
//Programmer: Ronnie Warden
//Date: 2.10.15
#include<iostream>
#include "link.h"
using namespace std;

/*************************************************************************************************************
Function: createNode
Parameters: No parameters
Return Type: Pointer to new node
Task: Create a node with "new" operator. Get a student data from keyboard and assign to members of the node.
*************************************************************************************************************/
Node createNode()
{
Node *newNode = new Node;
    cout << "Last Name?" << endl;
    cin >> newNode->lastName;
    cout << "First Name?" << endl;
    cin >> newNode->firstName;
    cout << "ID?" << endl;
    cin >> newNode->idNumber;
return *newNode;
}
/**************************************************************************************************************
Function: insertNode
Parameters: Pointer to the linked list
Return Type: Pointer to the linked list
Task: insert a new node to the linked list sorted by student's ID number. If ID is already in list notify user 
***************************************************************************************************************/
Node insertNode(Node *list)
{
    Node *newNode = new Node;
    Node *tmp = new Node;
    *newNode = createNode();
    int id = newNode->idNumber;
    if (list == NULL)           //Insert in empty list
        list->next = newNode;
    else
    {
         *tmp = searchNode(list, id);
         if (tmp->idNumber == newNode->idNumber)
             {
                cout << "ID number already in list! Please try again with a different ID number." << endl;
                insertNode(list);
        }
    if (list != NULL)
    {
        Node *tmp = list;
         if (tmp->idNumber > newNode->idNumber)     //Insert as first
         {
             newNode->next = tmp;
            list = newNode;
        }
    while (tmp->idNumber < newNode->idNumber)   //Search for insertion point
    {   
                if (tmp->next == NULL)        //Insert at end
                            tmp->next == newNode;
        tmp = tmp->next;
        if (tmp->idNumber < newNode->idNumber && tmp->next->idNumber > newNode->idNumber && tmp->next != NULL)  //Insert in-between
        {
            newNode->next = tmp->next->next;
            tmp->next = newNode;
        }
        }
    }
}
return *list;
}
 /***************************************************************************************************************
Function: searchNode
Parameters: Pointer to the linked list, student ID number
Return Type: Pointer to the node with matched ID number
Task: Search the linked list by student Id number. Notify user if ID is not found
***************************************************************************************************************/
Node searchNode(Node *list, int id)
{
    Node *missing = new Node;
    if (list->idNumber == id)   //Checks if first node matches id number
         return *list;
    else 
    {
        Node *tmp = new Node;   //creates temporary pointer to scroll through list
        while (tmp->idNumber != id)
       {    
            if (tmp->next == NULL)  //checks if number is missing returns sentinel if not found
            {
                missing->idNumber = 9999;   
                return *missing;
            }
             tmp = tmp->next;
         }
     return *tmp;
     }
 }
/***************************************************************************************************************
Function: deleteNode
Parameters: Pointer to the linked list, student ID number
Return Type: Pointer to the list
Task: Delete a node from the list. Notify user if no node matches
***************************************************************************************************************/
Node deleteNode(Node *list, int id)
{   
    Node *tmp = new Node;
    *tmp = searchNode(list, id);    
return *list;
}
/***************************************************************************************************************
Function: printNode
Parameters: Pointer to the linked list
Return Type: None
Task: Display the linked list
***************************************************************************************************************/
void printNode(Node *list)
{
    Node *tmp = new Node;
    tmp = list;
    while (tmp != NULL)
    {
        cout << tmp->lastName << endl;
        cout << tmp->firstName << endl;
        cout << tmp->idNumber << endl;
        tmp = tmp->next;
    }
}

如果我在insertNode函数中注释掉整个else语句,我将停止获取seg错误,但当我调用打印时,它会打印3个空行,然后打印0。任何帮助都将不胜感激,如果真的出现了,我不使用类的原因是因为我不被允许,它必须在结构化数据类型中完成。

#ifndef LINK_H
#define LINK_H
struct Node {
    char lastName[20];
    char firstName[20];
    int idNumber;
    Node *next;
};
int menu();
Node createNode();
Node insertNode(Node*);
Node searchNode(Node*, int);
Node deleteNode(Node*, int);
void printNode(Node*);
#endif

您的主要问题是没有正确使用指针——您有点介于指针和对象之间。(我不打算说明这是C++中的C风格程序的事实)

例如:您的createNode()方法返回一个Node对象。它通过在堆上创建一个新的Node,然后返回该节点的内容来实现这一点。这意味着你实际上有内存泄漏。没有人记得放在堆中的节点的指针,因此它会泄漏。

我的第一步是让createNode()返回Node*

Node* createNode()
{
    Node *newNode = new Node;
    // All your cout/cin stuff
    return newNode;
}

我会对其他方法采用相同的模式——使用指针而不是对象。以searchNode()为例。因为您使用的是对象,所以需要一个特殊的"未找到"节点。如果使用指针,则可以为"未找到的情况"返回NULL(C++中最好为0)。您也不需要new和临时变量。

Node* searchNode(Node* list, int id)
{
    while(list != 0) {
        if (list->id == id) {
            return list;
        }
        // This only impacts the local list. It doesn't
        // permanently change the value of the list
        // passed in.
        list = list->next;
    }
    return 0;
}

对于searchNode()上的奖励积分:由于它是一个排序列表,一旦找到比您要查找的id大的id,您就可以停止搜索。

既然你已经完成了,你的插入方法就简单了一点:

  1. 从用户处获取新节点
  2. 检查它是否存在-如果存在,请删除刚刚创建的节点并给出错误
  3. 如果没有,请搜索列表并找到插入新节点的位置