2012-10-30 61 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绝对正确 –