简体   繁体   English

Seg Fault和Pointer问题

[英]Seg Fault and Pointer issues

Been working on this program for a couple of days in class and I keep getting seg faults. 在课堂上工作了几天这个程序,我不断遇到段错误。 I can comment out the part of code that I think is causing it and I stop getting the fault but then my print function doesn't work. 我可以注释掉我认为导致它的代码部分,并且我停止了错误但是我的打印功能不起作用。 I am picking up the c++ book tomorrow to help. 我明天要拿起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;
}

This following part is the one throwing the seg fault. 以下部分是抛出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;
    }
}

If I comment out the entire else statement in the insertNode function I stop getting the seg fault but then when I call to print it prints 3 blank lines and then 0. Any help would be appreciated, and if it comes up, the reason I didnt use classes was because I am not allowed to, it has to be done in structured data type. 如果我在insertNode函数中注释掉整个else语句,我就会停止获取seg错误但是当我调用print时它会打印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

Your main problem is that you're not using pointers right - you're kind of half way between pointers and objects. 你的主要问题是你没有正确使用指针 - 你在指针和对象之间的某种程度。 (I'm not going to address the fact that this is a C style program in C++) (我不打算解决这个问题,这是C ++中的C风格程序)

For example: Your createNode() method returns a Node object. 例如:您的createNode()方法返回一个Node对象。 It does this by creating a new Node on the heap and then returning that node's contents. 它通过在堆上创建一个新Node然后返回该节点的内容来实现。 This means that you've actually got a memory leak. 这意味着你实际上有内存泄漏。 No one has remembered the pointer to the node you put in the heap and so it leaks. 没有人记得指向你放入堆中的节点的指针,因此它会泄漏。

My first step would be to make createNode() return a Node* 我的第一步是让createNode()返回一个Node*

Node* createNode()
{
    Node *newNode = new Node;

    // All your cout/cin stuff

    return newNode;
}

I'd follow the same pattern with the other methods - use pointers rather than objects. 我会使用与其他方法相同的模式 - 使用指针而不是对象。 Take searchNode() as an example. searchNode()为例。 Because you're using objects, you need a special "Not Found" node. 因为您正在使用对象,所以您需要一个特殊的“未找到”节点。 If you use pointers, you can return NULL (preferable 0 in C++) for the "not found case". 如果使用指针,则可以为“未找到的大小写”返回NULL(在C ++中优选为0)。 You also don't need to new and temporary variables. 您也不需要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;
}

For bonus points on searchNode() : Since it is a sorted list, you can stop searching as soon as you find an id that is greater than the one you are looking for. 对于searchNode()上的奖励积分:由于它是一个排序列表,因此一旦找到大于您要查找的ID,就可以停止搜索。

Now that you've done that, your insert method is a bit simpler: 既然你已经完成了,你的插入方法有点简单:

  1. Get a new node from the user 从用户获取新节点
  2. Check if it exists - if so delete the node you just created and give error 检查是否存在 - 如果是,请删除刚刚创建的节点并给出错误
  3. If not, search the list and find where to insert your new node. 如果没有,请搜索列表并找到插入新节点的位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM