悬空指针和内存泄漏之间的区别

时间:2012-10-30 04:48:28

标签: c

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

8 个答案:

答案 0 :(得分:135)

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 = malloc(10);
}
//ch not valid outside, no way to access malloc-ed memory

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

答案 1 :(得分:21)

您可以将这些视为彼此的对立面。

当你释放一个内存区域但仍保留一个指向它的指针时,那个指针悬空:

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!

答案 2 :(得分:15)

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

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

它们的相关之处在于它们都是与错误管理指针有关的情况,特别是关于动态分配的内存。在一种情况下(悬空指针)你可能释放了记忆但后来试图引用它;在另一方面(内存泄漏),你忘记了完全释放内存!

答案 3 :(得分: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的地址变为死并且指针仍然指向ptr仍然指向该位置。

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

内存泄漏

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

答案 4 :(得分:3)

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

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

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

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

答案 5 :(得分:3)

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

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

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

myarea=newarea;

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

char *p =NULL;

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

答案 6 :(得分: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); 
 }

有关更多信息,请单击HERE

答案 7 :(得分:0)

  

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

     
      
  1. 取消分配内存
  2.   
  3. 函数调用
  4.   
  5. 变量超出范围
  6.   

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