Gab*_* Re 3 c++ c++11 c++14 c++17
int*& f(int*& x, int* y){
int** z = &y;
*z = x;
return *z;
}
Run Code Online (Sandbox Code Playgroud)
大家好,我在考试中得到了这段代码,但我遇到了一些问题。
我的理解是,给定对函数体中构造的指针 (x) 和指针副本 (y) 的引用,将创建本地双指针 (z) 并用 y 左值初始化,然后取消引用 1 次,因此 y 正在被访问,并且 y 中包含的地址现在变成 x 中包含的地址。之后 *z 作为指针引用返回,我假设为 y。
如果我之前的部分是正确的,我不会解释为什么返回在函数退出时被释放的 y (因为临时参数)不会在程序中产生任何问题,实际上考试答案是该函数返回一个悬空参考,我同意这一点,但是,复制/粘贴代码,并“播放”返回的变量,甚至在返回参数后进行随机操作,以便“编辑堆栈”,其中释放的 y 仍然存在并且“准备被覆盖”(如果我仍然是对的)不会出现程序的任何未定义的行为。
我唯一的解释是,返回仅复制 y 中包含的右值,或者可能返回左值和右值(因为返回对指针的引用),但当与外部指针“调用”函数 y 关联时,它不会没有得到正确的释放,或者以某种方式获取值的指针取代了被释放的 y 指针。
在底部您可以找到用于测试函数 int*& f(int*&, int*) 的代码。
我的问题是:这是一个正确的悬空引用,还是可以在程序中使用这样的东西的边界情况?
#include <iostream>
using namespace std;
int a = 65;
int*& f(int*& x, int* y)
{
cout<<"indirizzo di y: "<<&y<<endl;
cout<<"indirizzo di x: "<<&x<<endl;
int** z = &y;
cout<<"indirizzo di *z prima: "<<*z<<endl;
*z=x;
cout<<"indirizzo di *z dopo: "<<*z<<endl;
cout<<"y punta a: "<<y<<endl;
cout<<"z dopo: "<<z<<endl;
return *z;
}
int*& crashaFisso() //function that crashes every time with a "proper" dangling reference
{
int a=10;
int* x =&a;
return x;
}
int main()
{
system("CLS");
int b = 20;
int codicerandom=0;
int* i = &a;
cout<<"indirizzo di i: "<<i<<endl;
int* u = &b;
cout<<"indirizzo funzione: "<<&f(i,u)<<endl;
int* aux = f(i,u);
int* crash = crashaFisso();
cout<<"crash: "<<*crash<<endl;
cout<<"aux: "<<*aux<<endl;
for(int i=0;i<100;i++)
codicerandom +=i;
for(int i=0;i<100;i++)
codicerandom +=i;
for(int ji=100;ji>0;ji--)
{
codicerandom +=ji;
for(int x=100;x>0;x--)
{
codicerandom -= x*2;
}
}
cout<<codicerandom<<endl;
cout<<"crash: "<<*crash<<endl;
cout<<"aux: "<<*aux<<endl;
cout<<"crash: "<<*crash<<endl;
cout<<"aux: "<<*aux<<endl;
a=32;
cout<<"aux: "<<*aux<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
考试答案是该函数返回一个悬空引用
正确的。
但是 (...) 不呈现程序的任何未定义行为。
是什么让你这么想的?未定义的行为并不意味着“程序无法正常工作”或“程序崩溃”。未定义的行为正如它所说的那样:行为不是由标准定义的。事实上,它可能“正确”工作(无论这意味着什么),标准并不禁止它。这就是为什么它如此危险。因为也许在你的测试中它工作正常,因为硬件、操作系统、特定编译器以及发生的一些其他假设。但问题是它不能保证正常工作。如果你改变机器、操作系统、编译器(甚至切换优化设置)、代码,甚至两天后编译它,它可能会表现得很奇怪,以一种(ekhm)未定义的方式。
一般来说,如果 UB 存在,则无法知道程序的行为是否正确。您试图通过思考左值、右值、分配等来分析情况,而现实情况是,当 UB 存在时,整个程序就没有意义了。你只是浪费时间。
不要写UB代码。不管它看起来是否有效。
| 归档时间: |
|
| 查看次数: |
433 次 |
| 最近记录: |