gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 07:16:27 25 4
gpt4 key购买 nike

#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 不应该是可见的?

最佳答案

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

  • iSet 中被放置在堆栈上。值 7 存储在那里,p 指向内存中的那个位置。当您从 Set 返回时,值保留在内存中:堆栈没有被“销毁”,只是重置了堆栈指针。 p 仍然指向这个位置,它仍然包含“3”的整数表示。

  • Use 中,d 重用了堆栈上的相同位置。

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

  • 在第二种情况下,它首先用 double 值 3.0 覆盖该值,然后将前 4 个字节解释为整数值以评估 *pd+=*p 中。

这个案例说明了为什么返回局部变量的指针/引用是一件坏事:在编写函数 Set 时,您甚至可以编写某种单元测试,但它们不会检测到错误。它可能直到软件投入生产并且必须执行一些非常关键的任务时才被注意到,然后就失败了。

这适用于所有类型的“未定义行为”,尤其是在像 C/C++ 这样的“低级”语言中。糟糕的是,“未定义”很可能意味着“完美地工作,直到为时已晚”......

关于c++ - 当指针引用的值不再存在时冲突输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20160847/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com