当指针引用的值不再存在时,输出冲突

时间:2013-11-23 09:48:17

标签: c++ function pointers

#include<iostream.h>
#include<conio.h>
int *p;
void Set()
{
   int i;
   i=7;
   p=&i;
}
int Use()  
{
   double d;
   d=3.0;
   d+=*p;
//if i replace the above 3 statements with --> double d=3.0+*p; then output is 10          otherwise the output is some random value(address of random memory location)
//why is this happening? Isn't it the same? 
   return d;
}
void main()
{
   clrscr();
   Set();
   cout<<Use();
   getch();
}

我的问题就像上面的评论中提到的那样。我想知道输出差异的确切原因。在上面的代码输出是随机存储器位置的一些地址,我明白这是因为我是一个局部变量Set()但是在第二种情况下它是如何可见的,即将它替换为double d = 3.0 + * p;因为那时输出是10(7 + 3),虽然7应该不可见?

2 个答案:

答案 0 :(得分:1)

使用指针p的结果是未定义的,它也可能会给你一个段错误或只返回42.你得到的结果背后的技术原因可能是:

  • i内的Set被放置在堆栈中。值7存储在那里,p指向内存中的该位置。从Set返回时,值仍保留在内存中:堆栈未被“销毁”,它只是重置的堆栈指针。 p仍指向此位置,该位置仍包含“3”的整数表示。

  • Use内,堆栈中的相同位置将重复用于d

  • 当编译器没有优化时,在第一种情况下(即一行中的整个计算),它首先使用值7(它仍然存在于内存中,p指向它) ,计算,覆盖值(因为你将它分配给位于同一位置的d并返回它。

  • 在第二种情况下, first 用double值3.0覆盖该值,然后将前4个字节解释为整数值,用于评估{{1}中的*p }}

这个案例说明了返回指向局部变量的指针/引用是如此糟糕:在编写函数d+=*p时,您甚至可以编写某种单元测试,但它们不会检测到错误。它可能会在软件投入生产之前被忽视,并且必须执行一些非常关键的任务,然后才会失败。

这适用于所有“未定义行为”的kindes,特别是在C / C ++等“低级”语言中。糟糕的是,“未定义”可能意味着“完全正常工作,直到为时已晚”......

答案 1 :(得分:0)

退出函数设置后,由于销毁局部变量i,指针p的值变为无效。该程序有不确定的行为。