簡體   English   中英

如何適當地初始化指針以避免 C++ 中的分段錯誤?

[英]How to initialize a pointer appropriately to avoid segmentation fault in c++?

我已經開始學習 c++(來自 java 背景)並且幾乎沒有達到指針並被卡住了。 當我調試這個程序時,它說,程序在行上收到了分段錯誤(SIGSEGV 信號)

*上一個=頭;

在下面的代碼中。

 #include <iostream>
 using namespace std;
 
 struct Node
 {
    int data;
    Node *link;
 };
 
 int main()
 {
 
    cout << "Starting main program \n";
    Node head;
    head.data = 0;
    head.link = NULL;
    
    cout << "After declaring head and initializing values \n";
    
    //Declaring a pointer variable which points to an entity of type struct.
    Node *previous;
    *previous=head;
    
    cout << "After declaring previous pointer \n";
    
    bool done = false;
    int i = 1;

    cout << "First while loop\n";   
    while(!done)
    {
        cout << i << ": Iteration";
        Node temp;
        temp.data=i;
        temp.link=NULL;
        if(i > 2)
        {
            done = true;
            continue;
        }
        *previous->link=temp;
        ++i;
        *previous = temp;   
    }
    
    done = false;
    
    cout << "Declaring temp pointer before printing \n";
    Node *temp;
    *temp = head;
    
    cout << "Second while loop\n";  
    while (!done)
    {
        cout << i << ": Iteration";
        if(temp == NULL)
        {
            done = true;
            continue;
        }
        cout << temp->data << "->";
        *temp = *temp->link;
    }
    cout << "NULL";
 }

為什么指針初始化不正確?

第一個問題:

Node *previous;
*previous=head;

第一行聲明 previous 將保存一個節點的地址。 它沒有被初始化,所以無論發生在堆棧上的任何值都將作為它保存的位模式被拾取。

不幸的是,第二行然后取消引用指針(指向垃圾)並嘗試將頭部復制到隨機內存中(因此導致崩潰)。

在這種情況下,您可能希望 previous 指向 head,即獲取 head 的地址並分配它:

Node* previous = &head;  // initialize at the point of declaration

但是,您還必須非常小心指向堆棧上聲明的變量的指針,因為當函數返回或作用域退出時,地址很快就會失效。 (通常帶有指針的數據結構使用在堆上分配的值,因此對象比聲明它們​​的函數存活時間更長。)

這就引出了第二個問題:

while(!done)
{
    cout << i << ": Iteration";
    Node temp;

已經有問題了。 temp在堆棧上的循環內聲明。 每次循環迭代,變量都會自動銷毀。 因此它不能在不破壞它的情況下參與你的鏈表。

您希望使用new創建列表節點,並且當您更新前一個的下一個指針時,您希望為其分配一個地址,而不是通過它復制對象。

像這樣的東西:

while(!done)
{
    cout << i << ": Iteration";
    Node * temp = new Node();
    temp->data = i;
    temp->link = nullptr;  // better than NULL
    if(i > 2)
    {
        break;
    }
    previous->link = temp;
    ++i;
    previous = temp;   
}

head對象可能也應該是堆分配的。 當然,現在您必須通過在所有節點上調用 delete 來處理清理內存。

代碼中有一些錯誤,但主要的錯誤是:-

  1. 您沒有為運行時添加的新節點分配內存
  2. 您正在創建結構實例,但您需要創建一個指向結構的指針(實例將在運行時創建(使用new運算符)

我在代碼中添加了注釋,解釋了我所做的更改究竟是什么。

這是修復:-

#include <iostream>
 using namespace std;
 
 struct Node
 {
    int data;
    Node *link;
 };
 
 int main()
 {
 
    cout << "Starting main program \n";
    // Allocating memory for the new instance of Node and making "head" pointing to it
    Node *head = new Node;
    head->data = 0;
    head->link = NULL;
    
    cout << "After declaring head and initializing values \n";
    
    //Declaring a pointer variable which points to an entity of type struct.
    Node *previous;
    // As head and previous both are pointers thus can be assigned as it is
    previous = head;
    
    cout << "After declaring previous pointer \n";
    
    bool done = false;
    int i = 1;

    cout << "First while loop\n";   
    while(!done)
    {
        cout << i << ": Iteration";
        
        // Allocating memory for the new instance of Node and making temp pointing to it
        Node *temp = new Node;  
        
        // As temp is a pointer thus using member access ("- >") operator to access the members
        temp->data=i;
        temp->link=NULL;
        
        if(i > 2)
        {
            done = true;
            continue;
        }
        
        previous->link = temp;
        ++i;
        previous = temp;
        
    }
    
    done = false;
    
    cout << "Declaring temp pointer before printing \n";
    Node *temp;
    temp = head;
    
    cout << "Second while loop\n";  
    while (!done)
    {
        cout << i << ": Iteration";
        if(temp == NULL)
        {
            done = true;
            continue;
        }
        cout << temp->data << "->";
        temp = temp->link;
    }
    cout << "NULL";
 }

暫無
暫無

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

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