悬挂指针和内存泄漏之间的区别
我不明白一个悬挂指针和内存泄漏之间的区别。 这两个词如何相关?
悬挂的指针指向已被释放的内存。 存储不再分配。 尝试访问它可能会导致分段错误。
常见的方法,以悬挂指针结束:
char* func() { char str[10]; strcpy(str,"Hello!"); return(str); } //returned pointer points to str which has gone out of scope.
你正在返回一个地址,这个地址是一个局部variables,当控制返回到调用函数时,这个variables已经超出了范围。 (未定义的行为)
另一个常见的悬空指针示例是通过指针访问内存位置,在该内存上显式调用空闲之后。
int *c = malloc(sizeof(int)); free(c); *c = 3; //writing to freed location!
内存泄漏是没有被释放的内存,现在没有办法访问(或释放它),因为没有办法再去。 (例如,一个指针是指向一个内存位置的唯一引用,它被 dynamic分配 (而不是释放),现在指向其他地方。)
void func(){ char *ch; ch = (char*) malloc(10); } //ch not valid outside, no way to access malloc-ed memory
Char-ptr ch是一个局部variables,在函数结束时超出范围,泄漏了dynamic分配的10个字节 。
你可以把它们看作是彼此的对立面。
当你释放一个区域的内存,但仍然保持一个指针,该指针悬而未决:
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!
一个悬挂的指针是一个有一个值(不是NULL),它引用了一些对你期待的对象types无效的内存。 例如,如果您设置一个指向对象的指针,然后用其他不相关的内容覆盖该内存,或者如果内存被dynamic分配,则释放该内存。
内存泄漏是当您从堆中dynamic分配内存但从不释放内存时,可能是因为您丢失了对它的所有引用。
它们是相关的,它们都涉及到pipe理不善的指针,特别是关于dynamic分配的内存。 在一种情况下(摇晃的指针),你可能已经释放了内存,但之后试图引用它; 在另一个(内存泄漏),你忘记完全释放内存!
摇摇欲坠的指针
如果任何指针指向任何variables的内存地址,但在指针仍然指向这样的内存位置之后,某个variables已从该内存位置删除之后。 这样的指针被称为悬挂指针 ,这个问题被称为悬挂指针问题。
#include<stdio.h> int *call(); void main(){ int *ptr; ptr=call(); fflush(stdin); printf("%d",*ptr); } int * call(){ int x=25; ++x; return &x; }
输出:垃圾值
注意:在某些编译器中,您可能会收到警告消息,返回本地variables或临时地址
说明:variablesx是局部variables。 它的范围和生命周期在函数调用之内,因此xvariablesx的返回地址变为死后,指针仍然指向ptr仍然指向该位置。
解决这个问题的方法:把variablesx作为静态variables。 换句话说,我们可以说一个指针对象被删除的指针被称为悬挂指针。
内存泄漏
在计算机科学中,当计算机程序错误地pipe理内存分配时会发生内存泄漏。 根据简单我们已经分配了内存而不是释放其他语言术语说不释放它调用内存泄漏对于应用程序和意外崩溃是致命的。
指针有助于将用户定义的范围创build为一个称为dynamicvariables的variables。 dynamicvariables可以是单个variables,也可以是同一types( array
)或不同typesvariables( struct
)的variables组。 当控制进入一个函数时,默认的局部variables作用域开始,当控制从这个函数中出来时,结束。 默认的全局可扩展范围从程序执行开始,一旦程序结束就结束。
但是一个由指针保存的dynamicvariables的作用域可以在程序执行的任何时刻开始和结束,这必须由程序员来决定。 只有程序员不处理范围的末端时,悬浮和内存泄漏才会进入画面。
内存泄漏将发生如果一个程序员,没有写dynamicvariables作为范围的结束代码( free
指针)。 任何方式一旦程序退出完整的进程内存将被释放,当时泄漏的内存也将被释放。 但是对于一个运行时间长的进程来说,会造成一个非常严重的问题。
一旦dynamicvariables的作用域结束(释放), NULL
应该被分配给指针variables。 否则,如果代码错误地访问它,则会发生未定义的行为。 所以悬挂的指针只不过是指向一个已经完成的dynamicvariables的指针。
内存泄漏 :堆中存在内存区时,堆栈中没有指向该内存的variables。
char *myarea=(char *)malloc(10); char *newarea=(char *)malloc(10); myarea=newarea;
悬挂指针 :当堆栈中的指针variables但堆中没有内存时。
char *p =NULL;
试图在不分配空间的情况下解引用的悬挂指针将导致分段错误。