パブリックメンバ関数からのポインタのベクトル/マップを返すC ++

私は、クラス内のパブリックメンバ関数からポインタのベクトルまたはマップへのポインタを返すことの意義について簡単に質問します。

ここに私のコードです:

ここではクラスBのメンバー関数です

vector* ClassB::getfunction(){
    returns m_test;
}

m_testは、ポインタのベクトルへのポインタ型のクラスBのプライベートデータメンバです。このオブジェクトはヒープ上で初期化されるので、クラスのデストラクタ(ベクトルのすべての要素を含む)で削除する必要があります。

私は次のように関数を使用します。

B* ex_B = new B();

vector* ex_ptr_vecA = new vector;  

ex_ptr_vecA = ex_B->getfunction();

私の質問:

私は2つのオブジェクトを持っているので、メモリは両方ともヒープ上に割り当てられていますので、両方を削除する必要がありますか?

秩序が重要で、次のことが正しいのでしょうか?

B* ex_B = new B();

vector* ex_ptr_vecA = new vector;  

ex_ptr_vecA = ex_B->getfunction();

//do something with ex_ptr_vecA
//Then I want to delete the allocate memory to the heap

//delete class B first
delete ex_B;

//and then the vector
//need to loop over vector elements and delete one at a time
for(int i =0; i < ex_ptr_vecA; i++){
     delete ex_ptr_vecA->at(i);
}

delete ex_ptr_vecA;

Bクラスのデストラクタが既にヒープメモリの割り当てを解除しているため、これが正しいのでしょうか、またはぶら下がっているポインタを削除しようとしていますか?

0

3 答え

B* ex_B = new B();
vector* ex_ptr_vecA = new vector;

ここでは、2ブロックのメモリを割り当て、それらのブロックの先頭のアドレスを対応するポインタ変数に格納しました。大丈夫だ。

ex_ptr_vecA = ex_B->getfunction();

Now you've reassigned ex_ptr_vecA with whatever address getfunction() returns. You no longer hold the address that new vector returned, you can't free it anymore, hence you've got a memory leak.

If you only need the pointer to ex_B's internal vector then simply say this:

vector* ex_ptr_vecA = ex_B->getfunction();

あなたのサンプルコード ex_ptr_vecA に示した方法は、 ex_B クラスで割り当てたのと同じベクトルを指しています。 ex_B がその内部ベクトルをデストラクタで削除した場合、 delete ex_ptr_vecA; は2回削除することを意味します。

1
追加された

私はライン

ex_ptr_vecA = ex_B->getfunction();

compiles (you assign "vector of pointers" => "pointer to vector of pointers"), you'll need only two deletes. B owns the pointer returned in ex_ptr_vecA, so it and only it is responsible for its destruction. Your code corrected:

B::B() : m_test( new vector() ) {}
B::~B() { delete m_test; }

B* ex_B = new B();
vector* ex_ptr_vecA;
ex_ptr_vecA = ex_B->getfunction();
// Do something
delete ex_B;

ご存じのように、このコードについてのポイントは、すべての新規コードが同じレベルのコードで削除され、割り当てと解放を考えるのを容易にするということです。これをさらに単純化するために、RAIIについて読んでください。

1
追加された
ああ、申し訳ありませんTypo。ポインタのベクトルへのポインタを返す必要があります。これでも私には同じ結果が得られますか?
追加された 著者 MWright,
ex_Bを削除するだけですか?上記のコードの解決策を教えてください。
追加された 著者 MWright,
@MWright:はい、そうです。 m_testがBに属している場合(read:Bのメンバ)、Bだけがm_testを削除する必要があります。 scoped_ptrと参照を使用すると、これを明確にすることができます。
追加された 著者 thiton,
@MWright:完了。
追加された 著者 thiton,

割り当て

ex_ptr_vecA = ex_B->getfunction();

によって割り当てられたメモリがメモリリークを引き起こします。

new vector

その後はアクセスできない。そのメモリへのポインタがないので、それを解放する機会はありません...

共有スマートポインタを使用することをお勧めします。割り当てられたメモリを解放し、順序を忘れることができます。

0
追加された
クラスBのデストラクタがメモリを割り当て解除すると、ClassBを削除した後のケースですか?
追加された 著者 MWright,
そのメモリ上のポインタは、getfunction()によって返された他のポインタによって上書きされるため...
追加された 著者 vitakot,