为什么在循环中创建的对象具有相同的地址

Why do the objects created in a loop have the same address?

本文关键字:地址 对象 循环 创建 为什么      更新时间:2023-10-16

我确实看到了一些其他看起来像我的问题,但我仍然无法弄清楚。

这是我的代码:

#include<iostream>
#include <vector>
using namespace std;
template<typename Data_Type>
class node {
public:
Data_Type data;
node* next;
node(Data_Type data, node* next){
this->data = data;
this->next = next;
}
};

int main(){
vector<node<int> > vectorOfNodes;
for (int i = 0; i< 4; i++){ 
node<int> newNode = node<int>(i,NULL);
std::cout << "new node address a "<<    &newNode << "n";
vectorOfNodes.push_back(newNode);
std::cout << "new node address b "<<    &vectorOfNodes[i] << "n";
}
for (int i = 0; i< 4; i++){ 
std::cout << "data "<<    vectorOfNodes[i].data << "n";
}
}

当我运行这个程序时,"新节点地址a"总是相同的地址,每次重复,但"新节点的地址b"每次都是不同的地址。

new node address a 0x7fff546c39b0
new node address b 0x7fe2f8c039d0
new node address a 0x7fff546c39b0
new node address b 0x7fe2f8c039f0
new node address a 0x7fff546c39b0
new node address b 0x7fe2f8c03a20
new node address a 0x7fff546c39b0
new node address b 0x7fe2f8c03a30
data 0
data 1
data 2
data 3

我不明白为什么a和b不一样。更具体地说:不是吗;newNode我刚刚创建的对象的地址?vectorOfNodes[i]不是也是那个对象吗?不是吗;vectorOfNodes[i]还是对象的地址?

每一门大学级别的操作系统设计和/或编译器设计课程都会解释这些内容。

有问题的对象在堆栈上被实例化,在作用域结束时,它们超出了堆栈的作用域。堆栈相应地增长和收缩,因为在循环的每一次迭代中,都会创建(和销毁)相同的对象,堆栈的增长和收缩量相同,所以相同的对象最终总是在堆栈上的相同位置实例化。

在实践中,编译器可以进行一些优化,并在大多数情况下计算出每个函数将使用的大量堆栈,从而将堆栈"预编译"为函数所需的大量堆栈;但这有点太过分了。。。

这是我能给出的最简洁的答案,而不需要深入到堆栈是什么等的整个讲座中

现在,另一个对象被分配到堆上。将注意力集中在这样一个事实上,即在循环结束时,您填充到向量中的对象仍然存在,而"a"对象被破坏,您将开始看到差异。在循环的每次迭代中,都会创建"a"对象,然后在循环结束时销毁(并在循环开始时再次创建),而填充到向量中的对象仍然存在。

push_back操作将newNode复制到向量中。因此,每个副本都在不同的地址。

此处;

node<int> newNode = node<int>(i,NULL);

你不是在创建一个新的节点,只是给它分配一个新值

正在使用默认的复制构造函数在向量内部创建新节点。如果你想让你的向量包含你正在推进的节点,你应该使用一个指针,就像这样;

vector<node<int>*> vectorOfNodes;