为什么不使用"new"运算符创建的对象获取相同的地址

hul*_*aba 2 c++ new-operator

通过这个问题,一个答案说创建的对象在其范围之外被销毁.为了清楚地理解这个概念,我编写了以下代码:

#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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到以下输出:

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 
Run Code Online (Sandbox Code Playgroud)

我知道每次循环迭代并创建一个新对象时,每个对象都会被销毁; 但为什么他们都有相同的地址.当我创建链接列表并且我没有使用new运算符创建对象而只是使用相同的代码时,我发生了这个问题,并且列表总是指向同一个节点,我遇到了无限循环.为什么为每个对象分配相同的地址?

dla*_*lle 6

您继续在堆栈顶部创建对象,然后将其删除(在每次循环迭代结束时对象超出范围,并在下一次迭代之前解构).因此,每次为对象分配空间时,堆栈顶部的地址都是相同的.

如果删除循环并Node连续分配多个s,则随着堆栈的增长,每个地方都会看到不同的地址.


Mak*_*gan 5

这与局部变量和作用域有关。由于变量somenode是在 for 循环的 {} 括号内声明的,因此它的作用域是 for 循环的本地范围。也就是说,它存在于 for 循环的单次迭代中,然后在下一次迭代开始之前超出范围。

编译器一般都尽量做到高效。在 for 循环的第一次迭代之后,地址0x7ffc32ff26b0指向内存中足以存储Node结构的位置。编译器还知道该内存未使用(超出范围),因此它认为它可以重新使用相同的内存位置。换句话说,虽然结构体占用相同的 RAM 内存,但它们都是独立的,彼此不相关。

这种行为是不能保证的,你不应该依赖它,它只是编译器试图使最终组装的代码尽可能简单和高效。