由c++循环中局部变量地址不变而引发的思考
2018-01-05 19:42
1751 查看
今天在用c++刷题的时候出现了一个bug,算法题所以免不了循环输入,而所有的代码自然也都嵌套在那个大循环中了。但是问题出现在:我在一个函数(不是main函数)的开头定义了一些局部变量(这个函数在程序中会被循环调用),但是既然是另外一个函数中定义的变量,我想着应该会在函数退出后自动释放了,那也就不需要每次循环都初始化一遍了。
然而事实上,如果不去给它初始化值的话,局部变量每次被声明后所在的地址是相同的,最可怕的是地址相同的话,里面的值就是上一次运行结束后的值。这也就意味着,c++在循环里面定义的变量的值在逻辑上是具有传递性的,当然可靠性不一定能保证。
下面直接放测试代码截图:
编译环境:codeblocks,语言:c++
第一张图:可以看出在
第二张图:上面说到值可以“继承”下来,那么地址真的不变吗?从下图中看出,地址确实是不变的,每次调用该函数后产生的变量
第三张图:这一次在
论坛里看到有人说
但是具体的原因仍旧不得而知了,希望以后能搞清楚这个问题。但是在刷题中要注意的是,在循环中,即便局部变量的申明也必须初始化!!!
然而事实上,如果不去给它初始化值的话,局部变量每次被声明后所在的地址是相同的,最可怕的是地址相同的话,里面的值就是上一次运行结束后的值。这也就意味着,c++在循环里面定义的变量的值在逻辑上是具有传递性的,当然可靠性不一定能保证。
下面直接放测试代码截图:
编译环境:codeblocks,语言:c++
第一张图:可以看出在
make函数中,如果不初始化
i,
i的值就是一个乱七八糟的数,但是初始化一次之后,即便以后不再初始化了,值也保留了下来。这很容易让人联想到
i的地址一直是不变的,所以下面就测试了一下地址。
第二张图:上面说到值可以“继承”下来,那么地址真的不变吗?从下图中看出,地址确实是不变的,每次调用该函数后产生的变量
i的地址都相同。这就让人疑惑了,它是根据什么来分配地址的呢?是请求分配地址的时间吗?于是进行了第三个实验。
第三张图:这一次在
make函数中分情况定义了两个不同名称的局部变量,如果传进来的参数t为偶数,就定义变量
i,并输出
i的地址,如果传进来的参数
t为奇数,就定义变量
j,然后输出它的地址。神奇的一幕发生了,
i的地址全都是相同的,
j的地址也都是相同的,但是
i和
j的地址是不同的。从第一次申请空间的时间来看,
j在
i之后,因此根据
c++局部变量控件分配到栈里,是从大到小的顺序,
j的地址比
i小4是没错的。但是第一次循环中
i的地址如果被释放,第二次进来申请
j的地址应该和第一次
i的地址是相同的,然而事实并没有。而编译器如果确实是按照顺序分配空间的话,第一次的i的空间有可能根本就没有被真正的释放,只是以某种外界不可访问的方式存在。
论坛里看到有人说
栈上的内存是顺序分配的, pop出来,再push进去。还是在原来的位置,这种说法应该是错误的,不然图三中
j的地址应该和
i的地址相同。
但是具体的原因仍旧不得而知了,希望以后能搞清楚这个问题。但是在刷题中要注意的是,在循环中,即便局部变量的申明也必须初始化!!!
相关文章推荐
- 由Google Log库glog循环打印到一行引发的C++知识点思考
- for语句引起一个死循环而引发的思考!!!
- 由循环次数设定引发的一些思考
- 助教:c/c++——数组元素奇偶排列:由此引发对if和while语句的简单问题的思考
- 由一个C++问题引发的讨论和思考(未完待续)
- C++中强迫隐式转换this对象到基类所引发的思考
- 一个c++题目引发的思考
- C++ 一道简单的题目引发的思考
- 一个C++程序编译失败引发的思考
- 网络安全宣传周系列:从泄露邮箱地址引发的思考
- 一次外场宕机引发对linux内存管理的进一步思考--Linux虚拟地址空间如何分布
- JavaScript 数组循环条件自减到0时引发的思考
- 虚拟地址引发的思考
- C/C++ waring:返回局部变量或临时变量的地址
- 由全排列问题引发的关于for循环里嵌套递归的思考
- 一道二级C题引发的思考-- c++函数传递指针的本质 与 字符串指针与字符数组的区别
- 一个例子引发的思考——C++内存地址
- 关于Android中为什么主线程不会因为Looper.loop()里的死循环卡死?引发的思考,事实可能不是一个 epoll 那么 简单。
- 囚犯生存概率引发的循环思考
- 虚函数地址C++虚函数的一点分析与思考