82

我不明白悬空指针和内存泄漏之间的区别。这两个术语有什么关系?

4

8 回答 8

148

悬空指针指向已释放的内存。不再分配存储。尝试访问它可能会导致分段错误。

以悬空指针结尾的常用方法:

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!

内存泄漏是尚未释放的内存,现在无法访问(或释放)它,因为再也无法访问它。(例如,一个指针,它是对动态分配(而不是释放)的内存位置的唯一引用,它现在指向其他地方。)

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

Char-ptr ch 是一个局部变量,在函数末尾超出范围,泄漏了动态分配的10 个字节

于 2012-10-30T04:49:48.740 回答
22

您可以将它们视为彼此的对立面。

当您释放内存区域但仍保留指向它的指针时,该指针悬空:

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!
于 2012-10-30T04:54:40.607 回答
16

悬空指针是一个具有值(非 NULL)的指针,它指的是对您期望的对象类型无效的一些内存。例如,如果您设置一个指向对象的指针,然后用其他不相关的东西覆盖该内存,或者如果它是动态分配的,则释放内存。

内存泄漏是当您从堆中动态分配内存但从未释放它时,可能是因为您丢失了对它的所有引用。

它们是相关的,因为它们都是与管理不善的指针有关的情况,尤其是在动态分配的内存方面。在一种情况下(悬空指针),您可能已经释放了内存,但之后尝试引用它;在另一个(内存泄漏)中,您忘记了完全释放内存!

于 2012-10-30T04:50:46.697 回答
6

悬空指针

如果任何指针指向任何变量的内存地址,但在某个变量从该内存位置删除之后,而指针仍指向该内存位置。这样的指针被称为悬空指针,这个问题被称为悬空指针问题。

#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 的地址后,x 变为死指针,指针仍然指向 ptr 仍然指向该位置。

此问题的解决方法:将变量 x 设为静态变量。换句话说,我们可以说指向对象已被删除的指针称为悬空指针。

内存泄漏

在计算机科学中,当计算机程序错误地管理内存分配时,就会发生内存泄漏。按照简单的说法,我们已经分配了内存,而不是 Free 其他语言术语说不释放它称为内存泄漏,这对应用程序和意外崩溃是致命的。

于 2013-07-19T06:32:42.637 回答
3

指针有助于为变量创建用户定义的范围,该变量称为动态变量。动态变量可以是单个变量,也可以是相同类型的变量array组( )或不同类型的变量组(struct)。默认局部变量范围在控制进入函数时开始,在控制离开该函数时结束。默认全局变量范围从程序执行开始,并在程序完成后结束。

但是由指针保存的动态变量的范围可以在程序执行中的任何点开始和结束,这必须由程序员决定。只有当程序员不处理范围的结尾时,悬空和内存泄漏才会出现。

如果程序员没有free为动态变量的范围结束编写代码(指针),则会发生内存泄漏。任何方式一旦程序退出完整的进程内存将被释放,此时泄漏的内存也将被释放。但是对于一个运行时间很长的进程,它会导致一个非常严重的问题。

一旦动态变量的范围结束(释放),NULL应该分配给指针变量。否则,如果代码错误地访问它,将发生未定义的行为。所以悬空指针只不过是一个指针,它指向一个作用域已经完成的动态变量。

于 2013-07-19T06:56:25.947 回答
3

内存泄漏:当堆中有一个内存区域但堆栈中没有指向该内存的变量时。

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

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

myarea=newarea;

悬空指针:当指针变量在堆栈中但在堆中没有内存时。

char *p =NULL;

尝试取消引用而不分配空间的悬空指针将导致分段错误。

于 2014-07-28T19:06:07.587 回答
0

指向已被删除(或释放)的内存位置的指针称为悬空指针。

#include <stdlib.h>
#include <stdio.h> 
 void  main()
 {
    int *ptr = (int *)malloc(sizeof(int));
    // After below free call, ptr becomes a 
    // dangling pointer
    free(ptr); 
 }

更多信息请点击这里

于 2018-07-03T13:59:49.087 回答
0

指向已被删除(或释放)的内存位置的指针称为悬空指针。Pointer 作为悬空指针有三种不同的方式。

  1. 内存的解除分配
  2. 函数调用
  3. 变量超出范围

—— 来自https://www.geeksforgeeks.org/dangling-void-null-wild-pointers/

于 2018-08-02T11:30:48.837 回答