c++ - 不将函数的返回值分配给变量的含义
问题描述
我正在做一些介绍性的 C++ 练习,其中之一是:运行这段代码后屏幕上会出现什么:
int& testMethod (int& a){
int c = a+a;
return c;
};
int main() {
int z = 5;
int* y = new int (testMethod(z));
int r = 25;
testMethod(r);
std::cout<<*y;
return 0;
}
我的问题是:
- 我是对的,这是 UB 的一个示例,因为
testMethod
第二次调用返回的值没有分配给变量吗? - 返回值虽然没有分配给变量,但是否仍然可以恢复,但这取决于?
对于第 2 点,我只是想确认我对堆栈如何工作的理解,如下所示。当一个函数返回一个值并且该值被分配给一个变量时,计算的结果首先被存储在堆栈中retval
的某个内存位置,然后被分配给该变量,即写入另一个内存位置。然后堆栈指针向上移动(同样,据我了解,堆栈的“顶部”实际上是它的“底部”,因为指针从最大地址移动到最小地址)。但是retval
仍然存在一段时间,直到它被另一条数据覆盖(这可能几乎立即发生)。
当我在 SO 上寻找第一个问题的答案并找到这个线程时,出现了第二个问题,因为两个顶部(通过投票)帖子的答案不同。
解决方案
如何在您的特定平台上实现自动分配无关紧要。您的代码确实testMethod
触发了 UB,不是因为您忽略了(顺便说一下,它不是方法)的返回值,而是因为以下行使用了它:
int* y = new int (testMethod(z));
问题是它testMethod
总是返回对其局部变量的悬空引用c
。使用此引用来初始化动态分配的int
触发器 UB。
可以预见的是,启用警告(您应该始终这样做)会产生以下结果:
warning: reference to stack memory associated with local variable 'c' returned [-Wreturn-stack-address]
推荐阅读
- java - 如何从可用作自定义实体 ID 生成器中实体 ID 的对象属性生成 UID?
- python - 在 OpenLDAP 中将用户添加到 POSIX 或“memberOf”组
- linux - 如何在不附加的情况下将文本写入 HDFS 中的文件
- powershell - 如何将多行批处理文件语句转换为 Powershell?
- google-analytics - 在 GTM 创建虚拟页面并将其发送到 GA 的问题
- python-3.6 - 为什么 -1*List 对象返回一个空列表?
- sql-server - 签名存储过程和应用程序角色安全冲突
- python - 如何在 docker 容器中使用相机
- python - 使用 Python 解析 xml 以提取 div 之间的内容
- javascript - 为什么反应应用程序的 node_modules/.cache/babel-loader 文件夹中有数百个 json 文件?