C++ 什么是悬空指针?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17997228/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:39:12  来源:igfitidea点击:

What is a dangling pointer?

c++pointersdangling-pointer

提问by code muncher

I know this is pretty common question, but still new for me!

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

I don't understand concept of dangling pointer, was googling around, and writing test methods to find one.

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

I just wonder is this a dangling pointer? As whatever example I found was returning something, here I'm trying something similar!

我只是想知道这是一个悬空指针吗?无论我发现什么例子都在返回一些东西,在这里我正在尝试类似的东西!

Thanks!

谢谢!

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...   
}

回答by Hyman

A dangling pointer is a pointer that points to invalid data or to data which is not valid anymore, for example:

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

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

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

This can occur even in stack allocated objects:

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

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

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

The pointer returned by c_strmay become invalid if the string is modified afterwards or destroyed. In your example you don't seem to modify it, but since it's not clear what you are going to do with const char *nameit's impossible to know it your code is inherently safe or not.

c_str如果字符串随后被修改或销毁,则返回的指针可能会变得无效。在您的示例中,您似乎没有修改它,但是由于不清楚您将要做什么,const char *name因此不可能知道您的代码是否本质上是安全的。

For example, if you store the pointer somewhere and then the corresponding string is destroyed, the pointer becomes invalid. If you use const char *namejust in the scope of new_foo(for example, for printing purposes) then the pointer will remain valid.

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

回答by Miklós Homolya

A dangling pointer is a (non-NULL) pointer which points to unallocated (already freed) memory area.

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

The above example should be correct given that the string is not modified through new_foo.

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

回答by MSalters

As a matter of style, I explain a dangling pointer as "a pointer which still exists, even though the object it pointed to no longer exists".

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

In your case, the pointer nameexists for a shorter period that the object that it points to. So it's never dangling.

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

Inside common C++ classes, pointers dangle for a very short period, inside destructors. That's because the deletestatement is before the last }of the destructor, while the pointer itself ceases to exist at the last }. If you don't want to worry about this, use e.g. unique_ptr<T>. The T*pointer will dangle for a very short time inside the unique_ptr::~unique_ptrdestructor, which is perfectly safe.

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

回答by Ashish Ahuja

Taken from here. Although, even if this is for C, it is the same for C++.

取自这里。虽然,即使这是针对 C 的,对于 C++ 也是一样的。

Dangling Pointer

悬空指针

If any pointer is pointing the memory address of any variable but after some variable has deleted from that memory location while pointer is still pointing such memory location. Such pointer is known as dangling pointer and this problem is known as dangling pointer problem.

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

Initially

最初

enter image description here

在此处输入图片说明

Later

之后

enter image description here

在此处输入图片说明

Example

例子

#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;
}

It's output will be garbage because variable x is local variable. Its scope and lifetime is within the function call hence after returning address of x variable x became dead and pointer is still pointing ptr is still pointing to that location.

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

回答by Avid Programmer

Dangling pointers is a situation where you have valid pointers in the stack, but it is pointing to invalid memory. You might end up in this situation when you deallocate the heap memory before the pointers in stack deallocated.

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

This is a security issue. Because when you deallocate a memory, we are informing Operating System, that we no longer need this section of memory. So OS will mark that piece of memory as ready to allocate and allocate to other applications when they request for memory.

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

Usually, in C++, memory allocated and deallocated through a general pattern. Constructor in a class gets invoked when a class initialised and this is the right place to allocate memory in heap.Destructor will be invoked when the class instance goes out of scope, and this is the right place to deallocate memory from heap. Assume we already created a class that does allocation and deallocation of memory in constructor and destructor respectively.

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

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

In the above example code, there are two variables declared but both holding the same value. When the constructor invoked, it allocates a heap memory. Then we are declaring one more variable and assigning the same value. In C++ usually, when you assign a value of complex type, it does a shallow copy (unless you explicitly implemented copy constructor) instead of deep copy. That means the only pointer gets copied in Stack, but not the heap memory. Actually it is not recommended to copy heap memory for performance reasons. Now the final memory layout looks like that we have two pointers pointing to the same heap memory.

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

Now when the function is done with execution, local variables goes out of scope and it invokes destructor. First, pointer2 invokes destructor that deallocates the heap memory. At this point, pointer1 becomes dangling pointer. It points to a memory that is already deallocated.

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

From this example, we understood that the primary cause of dangling pointer is having multiple owners for the same resource. Because when one pointer deallocates memory other pointers became dangling pointers.

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

回答by pavuluri santhi

Dangling Pointer and dangling pointer problem If any pointer is pointing the memory address of any variable but after some variable has deleted from that memory location while pointer is still pointing such memory location.

悬空指针和悬空指针问题如果任何指针指向任何变量的内存地址,但在某个变量已从该内存位置删除而指针仍指向该内存位置时。

That pointer is called as dangling pointer and the problem that arises at that time is called as dangling pointer problem.

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

Here are some examples: Dangling Pointer and dangling pointer problem

下面是一些例子:悬空指针和悬空指针问题