在循环中创建唯一对象指针

时间:2012-10-24 13:32:15

标签: c++

我需要在循环中创建对象指针,但我正在努力创建唯一指针。这是我的代码:

class DatClass{
  public:

  int m;

  DatClass(int i):m(i){}
};

class OtherClass{
  public:
  DatClass* dc;
};

void Test(std::vector<OtherClass> v){
  std::vector<OtherClass>::iterator it;
  int i = 1;
  for(it = v.begin(); it != v.end(); it++){
    DatClass dc = DatClass(i);
    std::cout << &dc << std::endl;
    it->dc = &dc;
    i++;
  }
}

int main(){
  std::vector<OtherClass> v;
  v.push_back(OtherClass());
  v.push_back(OtherClass());
  v.push_back(OtherClass());
  Test(v);
}

这并没有给我独特的指示。输出显示:

0xbf94d72c
0xbf94d72c
0xbf94d72c

我是否需要使用new才能获得独特的指针?如果是这样,我会把相应的删除放在哪里? 谢谢!

6 个答案:

答案 0 :(得分:3)

是的,您应该使用new来获取唯一地址。
delete应该在循环完成时 - 否则(删除在同一循环内) - 操作系统可以再次给你相同的地址。
(或者确切地说 - 当你完成了在这个地址中分配的对象时)

您的代码中发生的是您使用自动分配的内存。这个内存通常分配在堆栈上 - 在每次迭代中 - 相同的内存被重用于变量 - 因此它为您提供相同的地址。

答案 1 :(得分:2)

DatClass dc = DatClass(i);在堆栈上创建类的实例。它的地址在循环中保持不变,这就是输出相同的原因。

您可能想要执行以下操作:

void Test(const std::vector<OtherClass>& v){
  std::vector<OtherClass>::iterator it;
  for(it = v.begin(); it != v.end(); it++){
    const DatClass& dc = *it;
    std::cout << &dc << std::endl;
  }
}

答案 2 :(得分:1)

Test内循环的每次迭代都会在堆栈上创建一个新的DatClass实例并打印其地址。在下一次迭代之前,此对象的生命周期结束,这使编译器能够在下一次迭代中重用相同的内存。

这就是为什么你总是看到相同的地址(当然这只是因为标准特别允许编译器这样做)。

如果要查看对象的不同地址,则应该在循环外部的函数范围内分配所有这些地址(在这种情况下,它们将驻留在堆栈上但位于不同的地址),或者在堆上分配它们。

当然,显而易见的是vector本身包含的内容没有任何区别,因为这只会影响循环的迭代次数。如果更改代码以打印vector内实际对象的地址,您还会看到不同的地址。

答案 3 :(得分:0)

简短,你试图动态地这样做。这意味着nu不在堆栈上。因此,只有在您需要或不在程序启动时使用它时才会分配更多内存。

所以int a = 5; <<< stacknew int* b = 55(完成使用后,你必须释放delete b;的内存或稍后会出现的错误的分段错误错误。);

`cout<< &b;` prints the value  stored at the pointer ` 55`
`cout<< *b` prints the pointers value in memory `#1234` i think this is called offset

我要求你解决这个基本问题: http://www.cplusplus.com/doc/tutorial/

答案 4 :(得分:0)

我认为您可能正在尝试将 new DatClass分配给OtherClass,而是指定一个 auto (在堆栈上)DatClass,它在每个循环迭代,因为它是一个自动对象(并且编译器在堆栈上重用它的地址,这就是为什么你总是看到相同的地址)

我宁愿换掉这个:

for(it = v.begin(); it != v.end(); it++){
    DatClass dc = DatClass(i);           // auto object destroyed and address reused
    std::cout << &dc << std::endl;
    it->dc = &dc;

用这个:

for(it = v.begin(); it != v.end(); it++){
    DatClass *dc = new DatClass(i);      // new object on heap
    std::cout << dc << std::endl;
    it->dc = dc;

所以现在要创建 new DatClass对象以分配给OtherClass对象。 (此外,你还应该在delete那些新的DatClass对象,以避免资源泄漏)

答案 5 :(得分:-1)

您打印dc的地址。 dc每次都在同一位置的堆栈中。这就是为什么你每次都得到相同的地址。

您可以将循环更改为:

for (auto it = v.begin(); it != v.end(); ++it){
    OtherClass *oc = &(*it);
    std::cout << oc << std::endl;
}

,它为您提供v

中所有对象的地址