[英]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.