struct Node
{
int data;
Node * next;
Node (int x)
{
data=x;
next=NULL;
}
};
Node * insertInSorted(Node * head, int data)
{
Node* temp = new Node(data);
if (head == NULL){
return temp;
}
if (data < head->data){
temp->next = head
return temp;
}
Node* curr = head;
while (curr->next->data < data && curr->next != NULL){
curr = curr->next;
}
temp->next = curr->next;
curr->next = temp;
return head;
}
嗨,我最近學習了 C 并且一直在練習 LinkedList,這個問題很簡單,我要做的就是在保持排序順序的同時在正確的位置插入一個元素。我的問題是為什么我會遇到分段錯誤。我注意到在 while 回圈中,如果我將順序從while (curr->next->data < data && curr->next != NULL)翻轉到while (curr->next != NULL && curr->next-> data < data)分割錯誤不會發生。有人可以幫我理解這個問題嗎?
uj5u.com熱心網友回復:
你寫的方式,這個:
curr->next->data < data
在此之前評估:
curr->next != NULL
因此,curr->next當您嘗試在 中取消參考它時curr->next->data,它可以為 NULL ,因此您訪問記憶體的某些隨機部分并出現分段錯誤。
正如您所說,更改順序可以解決問題,這是正確的解決方案。當AND運算式的第一部分為假時,不會計算第二部分,因此您不會嘗試取消參考無效地址,因此您的問題已解決。
uj5u.com熱心網友回復:
這個while回圈
while (curr->next->data < data && curr->next != NULL){
curr = curr->next;
}
可以呼叫未定義的行為,因為在訪問資料成員之前沒有檢查是否curr->next等于。您需要交換邏輯 AND 運算子的運算元,例如nullptrcurr->next->data
while (curr->next != NULL && curr->next->data < data ){
curr = curr->next;
}
在任何情況下,如果使用指向指標的指標,則可以在不檢查大量條件的情況下撰寫函式,如下所示。
Node * insertInSorted( Node *head, int data )
{
Node *temp = new Node( data );
Node **current = &head;
while ( *current && !( data < ( *current )->data ) )
{
current = &( *current )->next;
}
temp->next = *current;
*current = temp;
return head;
}
請注意,您可以通過參考將指向頭節點的指標傳遞給函式。在這種情況下,不需要從函式回傳指向頭節點的指標。原始函式的用戶可能忘記將函式回傳的指標分配給函式呼叫者內的指標。
所以更安全的函式定義可以如下所示
void insertInSorted( Node * &head, int data )
{
Node *temp = new Node( data );
Node **current = &head;
while ( *current && !( data < ( *current )->data ) )
{
current = &( *current )->next;
}
temp->next = *current;
*current = temp;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/331742.html
