2012-02-10 135 views
2

運行某些C++代碼時,我遇到了段錯誤。我已經將問題隔離到程序中刪除指針的行。下面是產生同樣的錯誤一個簡單的例子:刪除指針時出現Segfault錯誤

int main() 
{ 
    int* pointer=0; 
    int number = 3; 

    pointer = &number; 
    delete pointer;//This line causes a segmentation fault 
    pointer=0; 

    return 0; 
} 

一個稍微的改變產生的代碼如預期,將工作:

int main() 
{ 
    int* pointer=new int(3); 

    delete pointer;//This line now works 
    pointer=0; 

    return 0; 
} 

有人可以解釋爲什麼首先使段錯誤和第二個不?我知道指針不是無效的,因爲它已被分配給數字變量的地址。

+4

第一個沒有分配'new',因此調用'delete'並不是正確的做法。 – ildjarn 2012-02-10 22:36:01

回答

14

您應該只有delete內存已被分配new。在堆棧中聲明的自動變量不需要爲delete d。作爲一項規則,總是與你的內存分配和釋放類型:與new分配

  • 內存應該delete被釋放。
  • 分配給new []的內存應該用delete []解除分配。
  • 分配到malloc()的內存應該用free()解除分配。

的段錯誤是因爲delete運營商將試圖把內存放回堆,並且依賴於那些不爲沒有來源的堆棧內存自動保持真實記憶的某些屬性從堆。

3

對於new沒有得到的東西,您不能使用delete。試圖這樣做會導致未定義的行爲。你的程序崩潰了,但什麼都可能發生。

0

如果您指針未分配new,則會在內存管理系統和堆棧之間產生衝突。每個操作都會像處理內存的唯一所有權一樣操作,並且當它們覆蓋對方的值時可能導致崩潰。

0

當您分配了新一variabile的:

int *a=new int(4); 

這個變量被放在堆,它包含了所有的內存分配dnamicly。 相反,如果你聲明一個變量:

int a=4; 

一個在棧中,那裏是靜態存儲器分配。 動態內存可以通過從用戶刪除來釋放,但靜態內存不能。

void function() 
{ 
    int a; 
} 

當函數結束時被自動釋放(除了與關鍵字「靜態」聲明的變量):當宥出口弗羅馬功能 靜態存儲器程序自動釋放。 主函數中的變量也會自動解除分配。 所以你不能說程序在堆棧中釋放一個變量。 在您的示例中,數字在堆棧中,指針指向堆棧中的數字,如果您刪除它,則嘗試刪除堆棧中的變量,這是不允許的,因爲它不是動態內存。

2

調用指針上的刪除,釋放指針指向的動態分配的內存。

在第一個程序中,指針指向一個靜態分配的內存位置。變量號是一個'自動'變量,這意味着它的內存是自動管理的。

另一方面,在第二個程序中,指針指向堆段中分配的內存位置,需要通過調用delete手動釋放該位置。

您可能會感興趣這個link有用。