我不明白悬空指针和内存泄漏之间的区别。这两个术语有什么关系?
Answers:
一个悬摆指针指向的内存已经被释放。不再分配存储空间。尝试访问它可能会导致分段错误。
结束于悬空指针的常见方法:
char *func()
{
char str[10];
strcpy(str, "Hello!");
return str;
}
//returned pointer points to str which has gone out of scope.
您返回的地址是一个局部变量,当控件返回到调用函数时,该变量将超出范围。(未定义的行为)
另一个常见的悬空指针示例是在该内存上显式调用free之后,通过指针访问内存位置。
int *c = malloc(sizeof(int));
free(c);
*c = 3; //writing to freed location!
一个内存泄漏是一个还没有被释放的内存,就没有办法访问(或释放它)现在,因为没有办法得到它了。(例如,指针是对动态分配(而不是释放)的内存位置的唯一引用,该指针现在指向其他位置。)
void func(){
char *ch = malloc(10);
}
//ch not valid outside, no way to access malloc-ed memory
Char-ptr ch是一个局部变量,在函数末尾超出范围,泄漏了动态分配的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!
悬空指针
如果任何指针指向任何变量的内存地址,但是在某个变量已从该内存位置删除之后,指针仍然指向该变量的内存位置。这样的指针称为悬空指针,而该问题称为悬空指针问题。
#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为静态变量。换句话说,可以说指针对象已被删除的指针称为悬挂指针。
内存泄漏
在计算机科学中,当计算机程序错误地管理内存分配时,就会发生内存泄漏。按照简单的方式,我们已经分配了内存,而不是免费的其他语言术语说不释放它称为内存泄漏,这对应用程序和意外崩溃是致命的。
指针有助于为变量创建用户定义的范围,该范围称为动态变量。动态变量可以是单个变量或相同类型array
的变量组()或不同类型的变量组(struct
)。默认局部变量作用域在控件进入功能时开始,并在控件脱离该功能时结束。默认全局可变作用域从程序执行开始,并在程序完成时结束。
但是,由指针保存的动态变量的范围可以在程序执行的任何时候开始和结束,这必须由程序员来决定。仅当程序员不处理范围的末尾时,晃动和内存泄漏才出现。
如果程序员不free
为动态变量的作用域结尾编写代码(指针),则会发生内存泄漏。程序退出后,将以任何方式释放完整的进程内存,这时泄漏的内存也将被释放。但是,这对于长时间运行的进程会造成非常严重的问题。
一旦动态变量的作用域结束(释放),NULL
应将其分配给指针变量。否则,如果代码错误地访问它,则会发生未定义的行为。因此,悬空指针不过是指向范围已完成的动态变量的指针。
内存泄漏:当堆中有一个内存区域,但堆栈中没有指向该内存的变量时。
char *myarea=(char *)malloc(10);
char *newarea=(char *)malloc(10);
myarea=newarea;
悬空指针:当指针变量在堆栈中但堆中没有内存时。
char *p =NULL;
悬空指针尝试取消引用而不分配空间将导致分段错误。
指向已删除(或释放)的内存位置的指针称为悬空指针。指针有三种悬空指针的方式。
- 内存分配
- 函数调用
- 变量超出范围
-来自https://www.geeksforgeeks.org/dangling-void-null-wild-pointers/