什么是悬垂指针?

时间:2013-08-01 14:45:21

标签: c++ pointers dangling-pointer

我知道这是非常常见的问题,但对我来说还是新的!

我不明白悬挂指针的概念,谷歌搜索,并编写测试方法来找到一个。

我只是想知道这是一个悬垂的指针吗?无论我发现什么样的东西都回来了,我在这里尝试类似的东西!

谢谢!

void foo(const std::string name)
{
    // will it be Dangling pointer?!, with comments/Answer
    // it could be if in new_foo, I store name into Global.
    // Why?! And what is safe then?
    new_foo(name.c_str());
}

void new_foo(const char* name)
{
    // print name or do something with name...   
}

7 个答案:

答案 0 :(得分:50)

悬空指针是指向无效数据或指向无效数据的指针,例如:

Class *object = new Class();
Class *object2 = object;

delete object;
object = nullptr;
// now object2 points to something which is not valid anymore

即使在堆栈分配的对象中也会发生这种情况:

Object *method() {
  Object object;
  return &object;
}

Object *object2 = method();
// object2 points to an object which has been removed from stack after exiting the function

c_str返回的指针可能会在之后修改字符串或被销毁时变为无效。在您的示例中,您似乎没有对其进行修改,但由于不清楚您要对const char *name执行什么操作,因此无法知道您的代码本质上是否安全。

例如,如果将指针存储在某处,然后销毁相应的字符串,则指针变为无效。如果仅在const char *name的范围内使用new_foo(例如,出于打印目的),则指针将保持有效。

答案 1 :(得分:10)

悬空指针是一个(非NULL)指针,指向未分配(已释放)的内存区域。

上面的例子应该是正确的,因为字符串没有通过new_foo修改。

答案 2 :(得分:4)

作为一种风格问题,我将一个悬空指针解释为“仍然存在的指针,即使它指向的对象不再存在”。

在您的情况下,指针name存在的时间比指向它的对象短。所以它永远不会悬空。

在常见的C ++类中,指针在析构函数内部存在很短的时间。那是因为delete语句在析构函数的最后}之前,而指针本身在最后}处不再存在。如果您不想担心这一点,请使用例如unique_ptr<T>T*指针将在unique_ptr::~unique_ptr析构函数中悬挂很短的时间,这是非常安全的。

答案 3 :(得分:3)

取自here。虽然,即使这是C语言,但C ++也是如此。

悬空指针

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

<强>首先

enter image description here

<强>后来

enter image description here

示例

#include<stdio.h>

int *call();
int main() {

  int *ptr;
  ptr = call();

  fflush(stdin);
  printf("%d", *ptr);
  return 0;
}

int * call() {
  int x=25;
  ++x;

  return &x;
}

它的输出将是垃圾,因为变量x是局部变量。它的范围和生命周期在函数调用内,因此在返回x变量x的地址变为死并且指针仍然指向ptr仍然指向该位置。

答案 4 :(得分:1)


//Declaring two pointer variables to int
int * ptr1;
int * ptr2;
// Allocating dynamic memory in the heap
ptr1 = new int;
ptr2 = ptr1; // Having both pointers to point same dynamic memory location
//deleting the dynamic memory location 
delete ptr1;
ptr1 = nullptr; 
//ptr2 is still pointing the already deleted memory location 
//We call ptr2 is a dangling pointer

答案 5 :(得分:0)

悬空指针是指堆栈中有有效指针,但它指向无效内存的情况。当您在释放堆栈中的指针之前释放堆内存时,可能会遇到这种情况。

这是一个安全问题。因为当您释放内存时,我们是在通知操作系统,我们不再需要此部分内存。因此,OS将在请求内存时将该内存标记为已准备好分配给其他应用程序。

通常,在C ++中,内存是通过常规模式分配和释放的。类初始化时将调用类中的构造方法,这是在堆中分配内存的正确位置。类实例超出范围时,将调用析构函数,这是从堆中释放内存的正确位置。假设我们已经创建了一个类,该类分别在构造函数和析构函数中分配和释放内存。

int main() {
  SomeClass pointer1 = SomeClass();
  SomeClass pointer2 = pointer1;
}

在上面的示例代码中,声明了两个变量,但是两个变量都具有相同的值。当构造函数被调用时,它将分配一个堆内存。然后,我们声明另一个变量并分配相同的值。通常在C ++中,当您分配复杂类型的值时,它将执行浅表副本(除非您明确实现了副本构造函数),而不是深表副本。这意味着唯一的指针将被复制到堆栈中,而不是堆存储器中。实际上,出于性能原因,不建议复制堆内存。现在,最终的内存布局看起来像我们有两个指向同一堆内存的指针。

现在,函数执行完毕后,局部变量超出范围,并调用析构函数。首先,pointer2调用析构函数来释放堆内存。此时,pointer1变为悬空指针。它指向已被释放的内存。

从此示例中,我们了解到指针悬空的主要原因是同一资源有多个所有者。因为当一个指针释放内存时,其他指针变成了悬空指针。

答案 6 :(得分:-1)

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

该指针被称为悬空指针,此时出现的问题称为悬空指针问题。

以下是一些示例:Dangling Pointer and dangling pointer problem