2013-08-01 65 views
32

我知道这是很常见的问题,但对我来说还是新的!什么是悬挂指针

我不明白晃来晃去的指针的概念,是谷歌搜索和编写测试方法 找到一个...我只是想知道这是一个悬挂指针吗?因为无论我发现什么样的东西都返回 的东西,在这里我正在尝试类似的东西! 谢谢!

void foo(const std::string name) 
{ 
    new_foo(name.c_str()); ///// 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? 
} 

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

*“!将它悬摆指针,有评论/回答是” * - 不,事实并非如此。你的第一个例子中没有悬挂指针。你在那里做的是完美的,100%安全和正确。 –

+0

我不明白你有没有*指针* *悬挂指针* ...。 –

+0

@TheOtherGuy我的意思是,没有const char * ...携带相同的const std :: string –

回答

38

悬空指针是指向了无效数据,或者其是无效的数据,例如一个指针:

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_foo的范围内使用const char *name(例如,出于打印目的),那么指针将保持有效。

+0

如果你修改了字符串的内容,那么你可以添加OP的示例并不是悬挂 – Angew

+0

IIRC,那么你使'c_str()'返回的指针无效,所以它可能被认为是悬挂的。 – Jack

+0

但字符串未被修改。即使在多线程应用程序中,也无法对其进行合法修改。 –

10

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

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

+0

...强调“*已经释放*”! – alk

+0

@MiklósHomolya它的“const”..你是什么意思在new_foo中修改?! –

+0

“const”的使用是(编译器)前端功能,可以通过const_cast来克服。问题在于如何以标准兼容的方式获取对栈变量'name'的引用,因为已经给出了函数'foo'的代码。 –

2

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

对于您的情况,指针name存在一个指向它的对象的较短时间段。所以它永远不会晃来晃去。

在常见的C++类中,指针在非常短的时间内在析构函数中晃动。这是因为delete声明在析构函数的最后一个}之前,而指针本身在最后的}处不复存在。如果您不想担心这一点,请使用unique_ptr<T>T*指针会在unique_ptr::~unique_ptr析构函数内暂停很短的时间,这非常安全。

2

摘自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之后仍然指向该位置。

-2

悬挂指针和悬挂指针问题 如果有任何指针指向任何变量的内存地址,但某些变量已从该内存位置删除,同时指针仍指向此内存位置。

该指针被称为悬挂指针,当时出现的问题称为悬挂指针问题。

下面是一些例子:Dangling Pointer and dangling pointer problem