C++ 什么是悬挂的指针?

C++ 什么是悬挂的指针?,c++,pointers,dangling-pointer,C++,Pointers,Dangling Pointer,我知道这是一个很常见的问题,但对我来说还是个新问题 我不理解悬空指针的概念,在谷歌上四处搜索,并编写测试方法来找到一个 我只是想知道这是一个悬空的指针吗?无论我发现什么样的例子是返回的东西,我在这里尝试类似的东西 谢谢 void foo(const std::string name) { //会不会是悬空的指针,带着评论/答案 //可能是在new_foo中,我将名称存储到Global中。 //为什么?!那么什么是安全的呢? new_foo(name.c_str()); } void new_fo

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

我不理解悬空指针的概念,在谷歌上四处搜索,并编写测试方法来找到一个

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

谢谢

void foo(const std::string name)
{
//会不会是悬空的指针,带着评论/答案
//可能是在new_foo中,我将名称存储到Global中。
//为什么?!那么什么是安全的呢?
new_foo(name.c_str());
}
void new_foo(常量字符*名称)
{
//打印姓名或用姓名做某事。。。
}

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

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
来执行,因此不可能知道您的代码本身是否安全

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

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


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

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

在您的例子中,指针
name
的存在时间比它指向的对象短。所以它永远不会摇摆不定

普通C++类,指针在很短的时间内会发生内含物析构函数。这是因为

delete
语句在析构函数的最后一个
}
之前,而指针本身在最后一个
}
处不再存在。如果您不想担心这一点,请使用例如
unique\u ptr
T*
指针将在
unique\u ptr::~unique\u ptr
析构函数内悬挂很短时间,这是非常安全的。

取自。虽然,即使这是C,C++也是一样的。 悬空指针 当指针指向某个变量的内存地址,但经过一段时间后,该变量从该内存位置删除,而指针仍指向该变量时,则该指针称为悬挂指针,该问题称为悬挂指针问题

最初

以后

示例

#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;
}
#包括
int*call();
int main(){
int*ptr;
ptr=call();
fflush(stdin);
printf(“%d”,*ptr);
返回0;
}
int*call(){
int x=25;
++x;
return&x;
}

它的输出将是垃圾,因为变量
x
是一个局部变量。它的作用域和生存期在函数调用中,因此在返回
x
变量
x
的地址后,该变量变为无效,指针仍指向该位置。

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

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


以下是一些示例:

悬空指针是指堆栈中有有效指针,但指向无效内存的情况。当在堆栈中的指针解除分配之前解除分配堆内存时,可能会出现这种情况

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

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

int main() {
  SomeClass pointer1 = SomeClass();
  SomeClass pointer2 = pointer1;
}
在上面的示例代码中,声明了两个变量,但都具有相同的值。当构造函数被调用时,它会分配一个堆内存。然后我们再声明一个变量并分配相同的值。在C++中,通常当赋值复杂类型时,它会做浅拷贝(除非显式实现复制构造函数)而不是深拷贝。这意味着在堆栈中只复制指针,而不复制堆内存。实际上,出于性能原因,不建议复制堆内存。现在,最终的内存布局看起来像是有两个指针指向同一堆内存

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

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

+(1/2)对于这个答案。开头的解释很好。最后的建议是第

//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