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必要があります-そうでない場合(削除は同じループ内にあります)-OSは再び同じアドレスを与える可能性があります。
(または正確には、このアドレスに割り当てられたオブジェクトを使い終わったとき)

コードで起こっていることは、自動的に割り当てられたメモリを使用することです。このメモリは通常、スタックに割り当てられ、各反復で同じメモリが変数に再利用されるため、同じアドレスが提供されます。

于 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; <<< stack、 (使用が終了したら、後で発生するセグメンテーション違反エラーnew 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;

これで、 OtherClassオブジェクトに割り当てる新しいDatClassオブジェクトを作成しています。delete(さらに、リソースリークを回避するために、これらの新しいDatClassオブジェクトもどこかに配置する必要があります)

于 2012-10-24T14:37:22.407 に答える
-1

のアドレスを出力しdcます。dc毎回同じ場所のスタックにあります。そのため、毎回同じアドレスを取得します。

ループを次のように変更できます。

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

内のすべてのオブジェクトのアドレスを提供しますv

于 2012-10-24T13:35:59.307 に答える