由c++循环中局部变量地址不变而引发的思考

今天在用c++刷题的时候出现了一个bug,算法题所以免不了循环输入,而所有的代码自然也都嵌套在那个大循环中了。但是问题出现在:我在一个函数(不是main函数)的开头定义了一些局部变量(这个函数在程序中会被循环调用),但是既然是另外一个函数中定义的变量,我想着应该会在函数退出后自动释放了,那也就不需要每次循环都初始化一遍了。
然而事实上,如果不去给它初始化值的话,局部变量每次被声明后所在的地址是相同的,最可怕的是地址相同的话,里面的值就是上一次运行结束后的值。这也就意味着,c++在循环里面定义的变量的值在逻辑上是具有传递性的,当然可靠性不一定能保证。
下面直接放测试代码截图:
编译环境:codeblocks,语言:c++

第一张图:可以看出在make函数中,如果不初始化ii的值就是一个乱七八糟的数,但是初始化一次之后,即便以后不再初始化了,值也保留了下来。这很容易让人联想到i的地址一直是不变的,所以下面就测试了一下地址。
这里写图片描述

第二张图:上面说到值可以“继承”下来,那么地址真的不变吗?从下图中看出,地址确实是不变的,每次调用该函数后产生的变量i的地址都相同。这就让人疑惑了,它是根据什么来分配地址的呢?是请求分配地址的时间吗?于是进行了第三个实验。
这里写图片描述

第三张图:这一次在make函数中分情况定义了两个不同名称的局部变量,如果传进来的参数t为偶数,就定义变量i,并输出i的地址,如果传进来的参数t为奇数,就定义变量j,然后输出它的地址。神奇的一幕发生了,i的地址全都是相同的,j的地址也都是相同的,但是ij的地址是不同的。从第一次申请空间的时间来看,ji之后,因此根据c++局部变量控件分配到栈里,是从大到小的顺序,j的地址比i小4是没错的。但是第一次循环中i的地址如果被释放,第二次进来申请j的地址应该和第一次i的地址是相同的,然而事实并没有。而编译器如果确实是按照顺序分配空间的话,第一次的i的空间有可能根本就没有被真正的释放,只是以某种外界不可访问的方式存在。

这里写图片描述

论坛里看到有人说栈上的内存是顺序分配的, pop出来,再push进去。还是在原来的位置,这种说法应该是错误的,不然图三中j的地址应该和i的地址相同。

但是具体的原因仍旧不得而知了,希望以后能搞清楚这个问题。但是在刷题中要注意的是,在循环中,即便局部变量的申明也必须初始化!!!

原文地址:https://www.cnblogs.com/yinyoupoet/p/13287545.html