簡體   English   中英

分段故障刪除節點

[英]segmentation fault deleting nodes

我在編譯此代碼時遇到了段錯誤,我相信它是由此處的此塊引起的。

EmployPtr iter;    
//Deletes nodes outside of range.
while(netSalary(iter)<45000 || netSalary(iter)>60000)
{
    EmployPtr nodeToDelete = iter;
    iter = iter->link;
    delete nodeToDelete;
}

我發現指針非常混亂,並且有一個指針沒有指向內存中的有效對象,但是我不確定如何解釋它。 我知道我需要在刪除對象之前將對象的“下一個”(或“鏈接”在我的代碼中如何命名)指針重新分配給該對象,再將其分配給下一個指針。 我試圖用代碼做到這一點,但我仍然遇到段錯誤。 誰能向我解釋發生了什么並幫助我了解如何解決此問題?

        EmployPtr nodeToDelete = iter->link;
        iter->link = nodeToDelete->link;
        delete nodeToDelete;

[包括其余的代碼,以防需要引用。]

#include <fstream>
#include <iostream>
using namespace std;

struct Employee
{
    string firstN;
    string lastN;
    float salary;
    float bonus;
    float deduction;

    Employee *link;
};

typedef Employee* EmployPtr;
void insertAtHead( EmployPtr&, string, string, float, float,float );
void insert( EmployPtr&, string, string, float, float,float );
float netSalary( EmployPtr& );

int main()
{
    //Open file
    fstream in( "payroll.txt", ios::in );

    //Read lines
    string first, last;
    float salary, bonus, deduction;
    EmployPtr head = new Employee;

    //Inserts all the data into a new node in the linked list, creating a new node each time the loop executes.
    while( in >> first >> last >> salary >> bonus >> deduction)
        insert (head, first, last, salary, bonus, deduction);

    //Close file
    in.close();

    cout << "\t\t\t\t-Salary in the range of ($45,000 - $60,000)-\n" << "Printed in format: First Name, Last Name, Salary, Bonus, Deduction, Net Salary.\n\n";

    //Deletes all nodes in the list that are not between 45,000 and 65,000. It then prints the newly modified list.
    EmployPtr iter;
    for(iter = head; iter!= NULL; iter = iter->link)
    {
        //Deletes nodes outside of range.
        while(netSalary(iter)<45000 || netSalary(iter)>60000)
        {
            EmployPtr nodeToDelete = iter;
            iter = iter->link;
            delete nodeToDelete;
        }

        //Prints list.
        cout << iter->firstN << ", " << iter->lastN << ", " << iter->salary << ", " << iter->bonus << ", " << iter->deduction << ", " << netSalary(iter) <<endl;
    }
        return 0;
}

void insertAtHead(EmployPtr& head, string firstValue, string lastValue,
            float salaryValue, float bonusValue,float deductionValue)
{
    //method definition
}

void insert(EmployPtr& afterNode, string firstValue, string lastValue,
        float salaryValue, float bonusValue,float deductionValue)
{
    //method definition
}

float netSalary(EmployPtr& node)
{
   //method definition
}

[更新代碼]

    //Deletes nodes outside of range.
    while((netSalary(head)<45000 || netSalary(head)>60000) && head!=NULL)
    {
        EmployPtr nodeToDelete = head;
        head = head->link;
        delete nodeToDelete;
        nodeToDelete->link = head;
    }

        //Prints List
    EmployPtr iter;
    for(iter = head; iter!= NULL; iter = iter->link)
    {
        cout << iter->firstN << ", " << iter->lastN << ", " << iter->salary << ", " << iter->bonus << ", " << iter->deduction << ", " << netSalary(iter) <<endl;
    }

在您的while周期中,迭代器可以指向列表的末尾,然后在netSalary(iter)中,您傳遞了空指針(如果我假設您的列表以空指針結尾)。 您的功能還可以嗎? 或者,您只有類似return iter-> salary的內容;

編輯:這只是一個猜測,因為您沒有提供方法的實現。

考慮當列表的最后一個元素的凈薪水低於45000或高於60000時會發生什么。最后一個元素的“鏈接”指針(可能)為NULL,但是您的內部循環不會對此進行檢查,因此在刪除該元素之后元素,它將向NETSalary函數傳遞一個NULL指針。

到達列表末尾時,您必須跳出循環。

我看到兩個類似的問題。

一種是您有兩次iter = iter-> link。 一次在for循環中,一次在while循環中。 您可能只需要一個控制循環。

另一個是while()循環從不檢查iter是否為null。

因此,請想象以下數據集:15000,16000

for循環指向15000節點。 現在,它打了while循環。 由於15000超出范圍,因此它進行iter = iter-> link,並且iter現在指向16000節點。 然后,它刪除15000節點。 while循環再次運行,發現16000超出范圍。 它執行iter = iter-> link,現在iter指向null。 刪除16000節點。 while循環再次運行,但是現在您將其傳遞為null!

我將其更改為使用while循環或for循環,並且只有一個位置檢查null並移至下一個節點。

我不知道是否要修復它,但我看到銷毀節點時並沒有刪除指向已刪除項目的先前鏈接。 我嘗試了一些東西,希望對您有所幫助

EmployPtr iter = head;
EmployPtr prevIt = NULL; // pointer to previous node
while( iter )
{
    if(netSalary(head)<45000 || netSalary(head)>60000)
    {
        EmployPtr nodeToDelete = iter;
        iter = iter->link;
        delete nodeToDelete;

        if( prevIt )
            prevIt->link = iter;
        else
            head = iter; // this happens when the head needs to be deleted, so head must point to nex
    }
    else
    {
        prevIt = iter;
        iter = iter->link;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM