2012-10-30 42 views

Trả lời

129

A dangling pointer chỉ vào bộ nhớ đã được giải phóng. Bộ nhớ không còn được cấp phát nữa. Cố gắng truy cập nó có thể gây ra lỗi Phân đoạn.

cách thông thường để kết thúc với một con trỏ tòn ten:

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

Bạn đang trả lại một địa chỉ mà là một biến địa phương, trong đó đã có thể đi ra khỏi phạm vi của sự kiểm soát thời gian được quay trở lại chức năng gọi điện thoại. (hành vi Undefined)

Một chung lơ lửng con trỏ ví dụ là một truy cập của một vị trí bộ nhớ thông qua con trỏ, sau khi miễn phí đã được rõ ràng kêu gọi ký ức đó.

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

Một memory leak là bộ nhớ mà chưa được giải thoát, không có cách nào để truy cập (hoặc miễn phí nó) bây giờ, khi không có những cách để có được nó nữa. (Ví dụ: một con trỏ mà tham chiếu chỉ đến một vị trí bộ nhớ cấp phát động (và không phải trả tự do) mà chỉ ở một nơi khác bây giờ.)

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

Char-ptr ch là một biến địa phương mà đi ra khỏi phạm vi ở phần cuối của hàm, rò rỉ được phân bổ động 10 byte.

+0

Bài viết này cũng có thể hữu ích http://stackoverflow.com/questions/127386/in-visual-studio-c-what-are-the-memory-allocation-representations – bkausbk

13

A dangling pointer là giá trị có giá trị (không phải NULL) tham chiếu đến một số bộ nhớ không hợp lệ đối với loại đối tượng bạn mong đợi. Ví dụ, nếu bạn đặt con trỏ đến một đối tượng thì ghi đè bộ nhớ đó bằng một thứ khác không liên quan hoặc giải phóng bộ nhớ nếu nó được cấp phát động.

A memory leak là khi bạn tự động cấp phát bộ nhớ từ heap nhưng không bao giờ giải phóng bộ nhớ, có thể do bạn mất tất cả các tham chiếu đến bộ nhớ đó.

Chúng có liên quan ở chỗ chúng là cả hai tình huống liên quan đến con trỏ bị quản lý sai, đặc biệt là về bộ nhớ được cấp phát động. Trong một tình huống (con trỏ lơ lửng) bạn có thể giải phóng bộ nhớ nhưng cố gắng tham khảo nó sau đó; trong khác (rò rỉ bộ nhớ), bạn đã quên để giải phóng bộ nhớ hoàn toàn!

20

Bạn có thể coi đây là sự đối lập của nhau.

Khi bạn giải phóng một vùng bộ nhớ, nhưng vẫn giữ một con trỏ đến nó, con trỏ được treo lủng lẳng:

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

Khi bạn bị mất con trỏ, nhưng giữ cho bộ nhớ được phân bổ, bạn có một rò rỉ bộ nhớ:

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

Dangling Pointer

Nếu bất kỳ con trỏ trỏ địa chỉ bộ nhớ của bất kỳ biến nhưng sau khi một số Varia ble đã xóa khỏi vị trí bộ nhớ đó trong khi con trỏ vẫn trỏ đến vị trí bộ nhớ đó. Con trỏ như vậy được gọi là con trỏ lơ lửng và vấn đề này được gọi là vấn đề con trỏ lơ lửng.

#include<stdio.h> 

    int *call(); 

    void main(){ 

     int *ptr; 
     ptr=call(); 

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

    } 

int * call(){ 

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

Output: giá trị rác

Lưu ý: Trong một số trình biên dịch, bạn có thể nhận thông điệp cảnh báo địa chỉ của biến cục bộ hoặc tạm

Giải thích trở về: biến x là biến cục bộ. Phạm vi và tuổi thọ của nó nằm trong hàm gọi do đó sau khi trở về địa chỉ của x biến x đã trở thành chết và con trỏ vẫn trỏ ptr vẫn trỏ đến vị trí đó.

Giải pháp của vấn đề này: Biến x là biến tĩnh. Nói cách khác, chúng ta có thể nói một con trỏ có đối tượng trỏ đã bị xóa được gọi là con trỏ lơ lửng.

Memory Leak

Trong khoa học máy tính, một rò rỉ bộ nhớ xảy ra khi một chương trình máy tính không đúng cách quản lý cấp phát bộ nhớ. Theo đơn giản chúng tôi đã phân bổ bộ nhớ và không miễn phí ngôn ngữ khác hạn nói không phát hành nó gọi rò rỉ bộ nhớ nó là gây tử vong cho ứng dụng và tai nạn bất ngờ.

3

Con trỏ giúp tạo phạm vi được xác định người dùng thành biến, được gọi là Biến động. Biến động có thể là biến đơn hoặc nhóm biến cùng loại (array) hoặc nhóm biến khác nhau (struct). Phạm vi biến cục bộ mặc định bắt đầu khi điều khiển nhập vào một hàm và kết thúc khi điều khiển đi ra khỏi hàm đó. Phạm vi mặc định toàn cầu mặc định bắt đầu khi thực hiện chương trình và kết thúc khi chương trình kết thúc.

Nhưng phạm vi của một biến động mà con trỏ giữ có thể bắt đầu và kết thúc tại bất kỳ điểm nào trong quá trình thực hiện chương trình, do một lập trình viên quyết định. Dangling và rò rỉ bộ nhớ đi vào hình ảnh chỉ khi một lập trình không xử lý kết thúc phạm vi.

Rò rỉ bộ nhớ sẽ xảy ra nếu một lập trình viên, không viết mã (free của con trỏ) cho cuối phạm vi cho các biến động. Bất kỳ cách nào một khi chương trình thoát khỏi bộ nhớ quá trình hoàn chỉnh sẽ được giải phóng, tại thời điểm đó bộ nhớ bị rò rỉ này cũng sẽ được giải phóng. Nhưng nó sẽ gây ra một vấn đề rất nghiêm trọng cho một quá trình đang chạy trong thời gian dài.

Khi phạm vi biến động được kết thúc (được giải phóng), NULL phải được gán cho biến con trỏ. Nếu không, nếu mã sai truy cập vào nó, hành vi không xác định sẽ xảy ra.Vì vậy, con trỏ lơ lửng là gì, nhưng một con trỏ trỏ một biến động có phạm vi đã được hoàn thành.

3

Rò rỉ bộ nhớ: Khi có vùng bộ nhớ trong vùng heap nhưng không có biến nào trong ngăn xếp trỏ đến bộ nhớ đó.

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

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

myarea=newarea; 

lơ lửng con trỏ: Khi một biến con trỏ trong một chồng nhưng không có bộ nhớ trong heap.

char *p =NULL; 

Con trỏ lơ lửng đang cố gắng bỏ qua mà không phân bổ không gian sẽ dẫn đến lỗi phân đoạn.

+3

ví dụ về con trỏ lơ lửng của bạn không thực sự là con trỏ lơ lửng nhưng con trỏ NULL. Ví dụ chính xác sẽ là gán động bộ nhớ cho con trỏ, nói sử dụng malloc(), và sau đó giải phóng() bộ nhớ đó, điều này làm cho nó trở thành một con trỏ lơ lửng. ** LƯU Ý: ** sau khi giải phóng chúng tôi chưa gán nó cho NULL do đó con trỏ vẫn trỏ đến cùng một địa chỉ bộ nhớ mà làm cho nó một con trỏ lơ lửng. Bây giờ, nếu bạn cố gắng truy cập bộ nhớ đó bằng cách sử dụng cùng một con trỏ (tức là dereference con trỏ), bạn có thể kết thúc nhận được lỗi phân đoạn. – sactiw

+1

@sactiw hoàn toàn đúng –

Các vấn đề liên quan