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

时间:2015-04-22 00:49:39

标签: c++ pointers

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

这是我的代码:

#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不一样。更具体地说:是不是&amp; newNode我刚刚创建的对象的地址?而且vectorOfNodes [i]也不是那个对象吗?那么&amp; vectorOfNodes [i]也不是对象的地址吗?

3 个答案:

答案 0 :(得分:10)

每个关于操作系统设计和/或编译器设计的大学课程都会解释这些内容。

有问题的对象在堆栈上实例化,并且在作用域的末尾,它们超出了堆栈的范围。堆栈相应地增长和收缩,并且因为在循环的每次迭代中,相同的确切对象被创建(和销毁),堆栈增长和收缩相同的量,因此相同的对象总是最终在同一位置实例化在堆栈上。

在实践中,编译器可以进行一些优化,并找出每个函数将使用的大量堆栈,大部分时间都是如此,因此&#34; pregrow&#34;堆栈到函数需要的大量;但这对杂草来说太过分了......

这是我能给出的简明回答,而不是进入整个讲座,了解堆栈是什么等等......

现在,另一个对象在堆上分配。将注意力集中在以下事实上:在循环结束时,您填充到矢量中的对象仍然存在,而&#34; a&#34;对象被破坏了,你将开始看到差异。在循环的每次迭代中,&#34; a&#34;对象被创建,然后在循环结束时被销毁(并在循环开始时再次创建),而填充到向量中的对象仍然存在。

答案 1 :(得分:0)

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

答案 2 :(得分:-2)

下面;

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

您没有创建新节点,只是为其分配新值。

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

vector<node<int>*> vectorOfNodes;