2017-04-23 81 views
3

我碰到this page,它说明了创建悬挂指针的常见方法。fflush()在悬挂指针方面做了什么?

下面是使用局部变量的返回地址说明悬摆指针代码:

在运行这个,这是编译器警告我得到(预期):

In function 'fun': 
12:2: warning: function returns address of local variable [-Wreturn-local-addr] 
    return &x; 
^

这是输出我得到(到目前为止好):

32743 

然而,当我合作mment了fflush(标准输出)线,这是输出我得到(使用相同的编译器警告):

5 

什么是这种现象的原因? fflush命令的存在/缺失如何导致此行为更改?

+1

http://stackoverflow.com/a/6445794/12711 –

+0

“*什么是对这种行为的原因是什么?*”这是**未定义行为**。你使用'fflush'是无关紧要的。 ('fflush'清空'stdout'的内容,但由于您没有缓冲内容,所以它没有任何合法的用途)。你可能会得到'5',你可能会得到一个'Segmentation Fault',它是** Undefined **。 –

回答

3

返回一个指针到堆栈上的对象是不好的,因为你所提到的。您只会看到fflush()调用存在问题的原因是,如果该堆栈不存在,堆栈将不会被修改。也就是说,5仍然存在,所以指针解引用仍然给你5。如果你调用一个函数在funprintf之间(几乎所有的功能,可能),它几乎肯定会覆盖该堆栈单元,使得后来值访问任何垃圾该功能发生了离开那里。

+0

不会printf()也放在栈上?这会导致指针指向的地址被其他东西(可能)覆盖? – Arpith

+0

任何事情都是可能的。显然,这不会发生在你的情况,但。 –

+0

我明白了。尝试了一个简单的睡眠(1),并做到了这一点。感谢您的帮助@CarlNorum – Arpith

0

这是因为调用fflush(stdout)写入到堆栈,其中x了。

让我解释一下。汇编语言中的堆栈(这是所有编程语言最终以这种或那种方式运行的)通常用于存储局部变量,返回地址和函数参数。当函数被调用时,它将这些东西推入堆栈:

  • 函数完成后继续执行代码的地址。
  • 的参数的功能,在由所使用的调用约定确定的顺序。
  • 函数使用的局部变量。然后

这些东西被弹出栈,一个接一个,通过简单地改变在这里CPU认为堆栈的顶部是。这意味着数据仍然存在,但不能保证继续存在。

fun()之后调用另一个函数覆盖堆栈顶部以上的值,在这种情况下值为stdout,因此指针的参考值发生更改。

如果不调用另一个函数,该数据保持在那里当指针被废弃仍然有效。

+2

我在系统上编码了一次,其中堆栈未用于局部变量和函数参数 –

+0

如果OP在x86或x86-64系统(大多数个人计算机)上编程,则使用堆栈局部变量和函数参数。如果他们在嵌入式系统上进行编程,那么理想情况下OP应该知道他们选择的系统的特质,并相应地采取行动。无论如何,返回一个指向局部变量的指针是未定义的行为。 – InternetAussie