在整数指针与字符指针的情况下悬空指针

Posted

技术标签:

【中文标题】在整数指针与字符指针的情况下悬空指针【英文标题】:Dangling pointer in case of integer pointer vs char pointers 【发布时间】:2018-05-12 17:50:16 【问题描述】:

我正在尝试了解悬空指针在 C++ 中的工作原理。

int* get_int_ptr()

    int i=10;
    int* ptr;
    ptr = &i;
    return ptr;


char* get_char_ptr()

    char str[10];
    strcpy(str,"Hello!");
    return(str); 


int main()

    cout << *get_int_ptr() << endl;
    cout << get_char_ptr() << endl;
    return 0;

这段代码的输出是-

警告:

prog.cpp: In function 'char* get_char_ptr()':
prog.cpp:16:9: warning: address of local variable 'str' returned [-Wreturn-local-addr]
char str[10];
    ^

输出:

10

有人能解释为什么i 的值会打印在main() 函数中,即使返回的指针指向超出范围的i

为什么str的值没有打印出来。

int*char* 在函数范围方面是分开处理的。

另外,在这里使用smart_pointers 是否会有所帮助?

【问题讨论】:

嗯,你无法理解悬空指针是如何“工作”的,因为它们不起作用!如果你想花精力去理解它们做了什么(即它们是如何失败的),请至少花同样多的精力确保你永远不会在真正的代码中使用它们! 解除对悬空指针的引用是Undefined Behaviour,这意味着任何事情都可能发生,包括看起来可以工作!该语言根本不做任何保证。只是碰巧在实际的硬件中,有时那块内存仍然包含以前的值,有时则没有。 "有人可以解释为什么 i 的值会打印在 main() 函数中,即使返回的指针指向超出范围的 i。"因为未定义的行为表明任何事情都可能发生。 基本上你的问题类似于“我没有驾照,为什么我能上车开车呢?”,或者“我在开车没有驾照。为什么没有警察拦住我?”也许警察稍后会阻止您,也许您永远不会被警察阻止,等等。基本上“未定义”会发生什么或不会发生什么。如果您在 C++ 中做一些非法/愚蠢的事情,同样的事情。由于未定义的行为,您无法保证会发生什么或不会发生什么。 【参考方案1】:

如您所知,返回指向局部变量的指针并不能保证有效。因此,您的 get_int_ptrget_char_ptr 函数都不能正常工作。

(预示答案:“不保证工作”与“保证不工作”不太一样。)

您尝试了 get_int_ptr 函数。令您惊讶的是,调用程序“正确”打印了 10。

这是一个类比。你所做的就像这个小故事:

我正在修车。我拆下前轮修理刹车。当我重新装上前轮时,我忘记安装凸耳螺母,所以***并没有真正固定。然后我开车去商店买了一些牛奶。但是***没有掉下来。为什么不呢?

答案是,你非常非常幸运。

然后您尝试了 get_char_ptr 函数。它失败了。这并不奇怪,除非您想象get_int_ptr 实验的成功以某种方式证明了悬空指针毕竟是可以使用的。继续类比:

第二天,在车轮螺母仍然不见的情况下,我开车越野去探望年迈的祖母。到了一半,在高速公路上以每小时 60 英里的速度行驶时,前轮突然飞了起来,我撞到沟里,把我的车毁了。为什么会这样?

不用说,这是因为缺少凸耳螺母!没有任何东西支撑着前轮,而你前一天明显的“成功”,在那种破烂的情况下开车去商店,证明什么都没有。

我同意有趣的是,您的一个功能“有效”而另一个没有。但这基本上是随机事件。不,int*char* 指针在这方面没有区别:如果悬空,它们几乎同样可能不起作用。

有时可以解释为什么随机事件会以这种方式发生。但是,在这里,我不能。我已经在我的编译器下尝试了你的程序,我看到的结果完全相同。 get_int_ptr 的局部变量 i 往往会存活下来,但 get_char_ptr 的局部数组 str 往往会被清除。我预计str 的部分可能会存活下来,但显然不会。但是,同样,我们无法解释这种行为并不重要,因为它是未定义的

【讨论】:

【参考方案2】:

打印某些内容是偶然的。

两个指针都指向当函数返回时不再存在的局部变量。

这是未定义行为的经典示例。

任何事情都可能发生 - 程序可能会为您点披萨、爆炸或打印一些东西 - 有时甚至是正确的值。

【讨论】:

以上是关于在整数指针与字符指针的情况下悬空指针的主要内容,如果未能解决你的问题,请参考以下文章

野指针 悬空指针和悬空引用

通过从本地 C 样式数组返回指针来获取悬空指针

为啥在指针和数组的情况下字符数组的处理方式不同? [复制]

悬空指针的含义[重复]

在没有指针的情况下复制 C 字符串中的单个字符

C语言指针的入门详细介绍