2

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

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 才能获得唯一的指针?如果是这样,我会将相应的删除放在哪里?谢谢!

4

6 回答 6

3

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

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

于 2012-10-24T13:33:41.383 回答
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;
  }
}
于 2012-10-24T13:36:20.273 回答
1

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

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

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

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

于 2012-10-24T13:35:36.930 回答
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/

于 2012-10-24T13:42:12.667 回答
0

我认为您可能正在尝试将一个的 DatClass 分配给 OtherClass,但是您分配的是一个自动(在堆栈上)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;

所以现在您正在创建新的DatClass 对象以分配给 OtherClass 对象。(此外,您还应该将delete那些新的 DatClass 对象放在某个地方,以避免资源泄漏)

于 2012-10-24T14:37:22.407 回答
-1

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

您可以将循环更改为:

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

它为您提供了所有对象的地址v

于 2012-10-24T13:35:59.307 回答