通过this question,一个答案说创建的对象在其范围之外被销毁。为了清楚地理解这个概念,我编写了以下代码:
#include <iostream>
using namespace std;
struct Node{
int val;
Node *next;
Node(int x) : val(x) , next(NULL){}
};
int main(){
for(int i=0;i<10;i++){
int someval = rand()%100;
Node somenode = Node(someval);
printf("Address for object %d is %p \n",i+1, &somenode);
}
}
我得到了以下输出:
Address for object 1 is 0x7ffc32ff26b0
Address for object 2 is 0x7ffc32ff26b0
Address for object 3 is 0x7ffc32ff26b0
Address for object 4 is 0x7ffc32ff26b0
Address for object 5 is 0x7ffc32ff26b0
Address for object 6 is 0x7ffc32ff26b0
Address for object 7 is 0x7ffc32ff26b0
Address for object 8 is 0x7ffc32ff26b0
Address for object 9 is 0x7ffc32ff26b0
Address for object 10 is 0x7ffc32ff26b0
我知道每次循环迭代并创建一个新对象时,每个对象都会被销毁;但为什么他们都有相同的地址。当我创建链接列表并且我没有使用new运算符创建对象而只是使用相同的代码时,我发生了这个问题,并且列表总是指向同一个节点,我遇到了无限循环。为什么为每个对象分配相同的地址?
答案 0 :(得分:6)
您继续在stack的顶部创建对象,然后将其删除(在每次循环迭代结束时对象超出范围,并在下一次迭代之前解构)。因此,每次为对象分配空间时,堆栈顶部的地址都是相同的。
如果删除循环并连续分配多个Node
,则随着堆栈的增长,每个地址都会看到不同的地址。
答案 1 :(得分:4)
这与局部变量和范围有关。由于变量somenode
是在for循环的{}括号内声明的,因此它的范围是for循环的局部范围。也就是说,它在for循环的单次迭代期间存在,然后在下一次迭代开始之前超出范围。
编译器作为一般尝试高效。在for循环的第一次迭代之后,地址0x7ffc32ff26b0
指向内存中足以存储Node
结构的位置。编译器也知道这个内存未被使用(它超出了范围),所以它认为它可以重用相同的内存位置。换句话说,尽管结构占据相同的RAM存储器,但它们都是独立的并且彼此无关。
这种行为无法保证,您不应该依赖它,它只是编译器尝试使最终汇编代码尽可能简单有效。