2012-10-30 60 views

回答

129

A dangling pointer指向已被釋放的內存。存儲不再分配。嘗試訪問它可能會導致分段錯誤。

常見的方式結束了一個懸空指針:

char* func() 
{ 
    char str[10]; 
    strcpy(str,"Hello!"); 
    return(str); 
} 
//returned pointer points to str which has gone out of scope. 

您在返回這是一個局部變量,它會被時間控制已超出範圍返回給調用函數的地址。 (未定義行爲)

另一個常見的懸掛指針的例子是通過指針的存儲器位置的訪問,免費後一直明確稱爲上存儲器。

int *c = malloc(sizeof(int)); 
free(c); 
*c = 3; //writing to freed location! 

還沒有被釋放的memory leak是記憶,是沒有辦法訪問(或免費吧)現在,因爲沒有辦法得到它了。 (例如,一個指針,它內存位置動態分配(而不是釋放),它指向別處現在唯一的參考。)

void func(){ 
    char *ch; 
    ch = (char*) malloc(10); 
} 
//ch not valid outside, no way to access malloc-ed memory 

炭火PTR CH是一個局部變量超出範圍在函數結尾處,泄漏動態分配的10字節

+0

本文可能也有幫助http://stackoverflow.com/questions/127386/in-visual-studio-c-what-are-the-memory-allocation-representations – bkausbk

13

A dangling pointer是一個值(不是NULL),它指的是某些對您所期望的對象類型無效的內存。例如,如果您設置一個指向對象的指針,然後用其他不相關的內容覆蓋該內存,或者如果內存被動態分配,則將其釋放。

A memory leak是您從堆中動態分配內存但從未釋放內存的原因,可能是因爲您丟失了對它的所有引用。

它們是相關的,它們都是關於錯誤管理指針的情況,尤其是關於動態分配內存的情況。在一種情況下(搖晃指針),你可能已經釋放了內存,但後來試圖引用它;在另一個(內存泄漏)中,你忘記完全釋放內存!

20

你可以將這些看作是彼此的對立面。

當你釋放的內存區域,但仍保持它的指針,該指針被晃來晃去:

char *c = malloc(16); 
free(c); 
c[1] = 'a'; //invalid access through dangling pointer! 

當你失去的指針,但保留分配的內存,你有內存泄漏:

void myfunc() 
{ 
    char *c = malloc(16); 
} //after myfunc returns, the the memory pointed to by c is not freed: leak! 
6

懸掛指針

如果任何指針指向任何可變的但某些雜物後的存儲器地址當指針仍指向此內存位置時,ble已從該內存位置刪除。這樣的指針被稱爲懸擺指針而這個問題被稱爲懸掛指針問題。

#include<stdio.h> 

    int *call(); 

    void main(){ 

     int *ptr; 
     ptr=call(); 

     fflush(stdin); 
     printf("%d",*ptr); 

    } 

int * call(){ 

    int x=25; 
    ++x; 
    return &x; 
} 

輸出:垃圾值

注:在一些編譯器,你可能會得到警告信息返回局部變量的地址 或臨時

說明:變量x是局部變量。它的範圍和生命週期都在函數調用中,因此在x變量x的返回地址變爲死亡並且指針仍然指向ptr之後仍然指向該位置。

解決此問題的方法:將變量x作爲靜態變量。 換句話說,我們可以說一個指針對象被刪除的指針稱爲懸掛指針。

內存泄漏

在計算機科學中,當一個計算機程序不正確地管理存儲器分配發生內存泄漏。 根據簡單我們已經分配了內存而不是釋放其他語言術語說不釋放它調用內存泄漏它是應用程序和意外崩潰致命。

3

指針有助於將用戶定義的範圍創建爲一個稱爲動態變量的變量。動態變量可以是單變量或同組變量(array)或不同類型的變量組(struct)。默認局部變量作用域在控制進入函數時開始,並在控制離開該函數時結束。默認的全局可擴展範圍從程序執行開始,一旦程序結束就結束。

但是,由指針保存的動態變量的作用域可以在程序執行的任意時刻開始和結束,這必須由程序員決定。只有程序員不處理範圍的末端時,懸浮和內存泄漏纔會出現。

如果程序員沒有爲動態變量的作用域結束寫入代碼(指針的free),將發生內存泄漏。任何方式一旦程序退出完整的進程內存將被釋放,那時泄漏的內存也將被釋放。但是對於一個運行時間很長的進程來說,這會造成一個非常嚴重的問題。

一旦動態變量的作用域結束(釋放),NULL應該被分配給指針變量。否則,如果代碼錯誤地訪問它,則會發生未定義的行爲。所以懸掛指針不過是一個指向動態變量的指針,其範圍已經完成。

3

內存泄漏:當堆中有內存區但堆棧中沒有指向該內存的變量時。

char *myarea=(char *)malloc(10); 

char *newarea=(char *)malloc(10); 

myarea=newarea; 

懸掛指針:當在堆棧指針變量,但在堆無記憶。

char *p =NULL; 

懸空指針試圖取消引用未分配空間會導致分段錯誤。

+3

你的懸掛指針的例子不是真的懸掛指針而是一個NULL指針。正確的例子是將內存動態分配給指針,比如使用malloc(),然後釋放()該內存,這使得它成爲一個懸掛指針。 **注意:釋放後**我們沒有將它分配給NULL,因此指針仍然指向相同的內存地址,這使得它成爲懸掛指針。 現在,如果您嘗試使用相同的指針訪問該內存(即取消引用指針),則可能會出現分段錯誤。 – sactiw

+1

@sactiw絕對正確 –