C ++ init for循环中的多个类对象给出了相同的内存地址?

时间:2018-02-05 14:32:33

标签: c++ memory initialization

我的代码片段如下,但是当我有2个自定义类并且我定义它们并打印它们的内存地址时:

for(int i=0;i<2;i++){
    Engine b;
    Strategy d;
    std::cout<<"be:"<<&b<<std::endl;
    std::cout<<"elm:"<<&d<<std::endl;
}

输出:

  

是:0x7ffd92aee2c0

     

榆树:0x7ffd92aede70

     

是:0x7ffd92aee2c0

     

榆树:0x7ffd92aede70

我期待两组不同的内存地址,但它们是相同的。有人能告诉我如何初始化到不同的地址吗?

4 个答案:

答案 0 :(得分:3)

  

我期待两组不同的内存地址

没有理由期待这一点。到下一次迭代开始时,前一次迭代中自动对象的生命周期已经结束,因此下一次迭代中的对象可以重用相同的存储,即它可以具有相同的内存地址。

  

有人可以告诉我如何初始化到不同的地址吗?

您无法指定分配自动存储持续时间对象的内存位置。但是,如果您创建两个生命周期重叠的对象,则它们必须存储在不同的地址中。约翰已经在answer中使用数组展示了如何做到这一点。

答案 1 :(得分:2)

显而易见的方法是

Engine b[2];
Strategy d[2];
for(int i=0;i<2;i++){
    std::cout<<"be:"<<&b[i]<<std::endl;
    std::cout<<"elm:"<<&d[i]<<std::endl;
}

但真正的问题是你关心地址是否相同的原因。很可能它不是你需要担心的事情。

答案 2 :(得分:1)

您输出的两个变量应该只有1个唯一的内存地址,即等于

  

0x7ffd92aee2c0

输出了两次,没有任何变化。

然后

  

榆树:0x7ffd92aede70

是同样的情况,你输出两次没有变化,你期望有什么不同?

代码工作正常!

答案 3 :(得分:1)

每次进入块时都会创建块范围内创建的对象,并在每次阻止块时将其销毁。在循环的情况下,您的对象bd将分别在迭代的每个开始和结束时创建和销毁。因此,每次迭代都会获得“新”对象,但编译器可以自由使用任何地址(甚至是用于先前迭代对象的地址),因此可能会一次又一次地看到相同的地址。但也可能会发生不同的情况。无论如何,依赖于生命时间已经结束/将要结束的对象的内存地址是没有意义的,所以更有趣的问题是:“为什么你关心ed的内存地址?吗?”。

要了解会发生什么,请尝试以下代码。它显示了在程序过程中如何创建和销毁对象:

class TestClass {
public:
    TestClass (int x=0) : x (x) { cout << "Constructing " << x << endl; };
    TestClass (const TestClass& t) : x (t.x) { cout << "CopyConstructing " << x << endl; };
    TestClass (const TestClass&& t) : x (t.x) { cout << "Moving " << x << endl; };
    ~TestClass () { cout << "Destructing " << x << endl; };

    int x;
};

int  main() {

    for(int i=0;i<2;i++){
        TestClass b(i);
        std::cout<<"elm:"<<&b<<std::endl;
    }    
}

输出:

Constructing 0
elm:0x7fff5fbff780
Destructing 0
Constructing 1
elm:0x7fff5fbff780
Destructing 1