2

C ++でオブジェクトをベクターに追加し、そのオブジェクトへのポインターを削除すると、ベクター内のオブジェクトも削除されますか?

例えば、

int i = 0;
std::vector<A> aVect;
while(i++ < 10)
{    
    A *ptrToA = new A();
    aVect.push_back(*ptrToA);
    delete ptrToA;
}

呼び出すことはまだ有効でしょうか:

aVect.at(2);

「削除」の呼び出しは、ベクターに追加されたオブジェクトを破棄しますか、それともポインターのオブジェクトの割り当てを解除するだけですか?

4

5 に答える 5

1

はい、ポインタを削除できます。他の人が指摘しているように、ポインタを逆参照すると、値によってベクトルにコピーされます。

このようにベクターを作成し、新規/削除を完全に回避する方が効率的です。

int i = 0;
while(i++ < 10)
{    
    std::vector<A> aVect;
    aVect.push_back(A());
}

C ++ 11では、コピーは作成されません-push_backの右辺値バージョンが使用されます-ベクトルのスロットにAが構築されます。

毎回新しいベクトルを作成したくない場合がありますか?

std::vector<A> aVect;
int i = 0;
while(i++ < 10)
{    
    aVect.push_back(A());
}
于 2013-02-02T20:34:46.210 に答える
1

aVect.at(2)ベクトルはのコピーを保持しているため、を呼び出すことは引き続き有効です*ptrToA。を呼び出すと、代入演算子を使用しaVect.push_back(*ptrToA)て設定します。A

于 2013-02-02T20:29:03.097 に答える
0

ここで、オブジェクトのコピーをベクターにプッシュすると、このコピーは削除されません。

ただし、次のように記述した場合:

int i = 0;
while(i++ < 10)
{    
    A *ptrToA = new A();
    std::vector<*A> aVect;
    aVect.push_back(ptrToA);
    delete ptrToA;
}

次に、ベクター内のポインターをプッシュします。削除するとptrToA、ベクター内のポインターが指す要素も削除されます。

于 2013-02-02T20:27:49.963 に答える
0

タイプA:のオブジェクトのベクターを作成しました。std::vector<A>これは、新しいオブジェクトを挿入すると、この新しいオブジェクトのコピーが作成され、ベクターに保存されることを意味します。

そうです、新しいオブジェクトが削除された後でも、この要素にアクセスすることは完全に安全で有効です。元のオブジェクトを削除しても、ベクターに保存されているコピーにはまったく影響しません。

この種のベクトル(自動保存期間を持つオブジェクトを保持するベクトル)の利点は、ベクトルが破棄されると、これらのオブジェクトが保存されているメモリが自動的にクリーンアップされることです。したがって、自分でその醜いメモリ管理を行う必要がないため、コードにメモリリークが発生する可能性が低くなり、作業も少なくなります:)

于 2013-02-02T20:28:08.050 に答える
0

いいえ、そうではありません。ポインタstd::vector<A>ではなくオブジェクトのインスタンスを格納します。実際、Aをベクトルにプッシュしている間、ポインターを逆参照しています。

これにより、オブジェクトのコピー(ビルドスルーcopy constructor)がベクター内に保存されます。オブジェクトをプッシュすると、Aクラスのインスタンスが2つあります。heap1つのインスタンスが(を介して)に割り当てられますnew operator。もう1つのインスタンスは、stackaVect割り当てられています。

一方、ベクトルがポインタ(std::vector<*A>)を格納する場合、削除後ptrToA、ベクトル内に格納されたポインタは、すでに解放されたメモリ位置(ダングリングポインタ)を指します。そのポインタにアクセスしようとすると、エラーが発生する可能性がありますsegfault

于 2013-02-02T20:28:30.057 に答える