2011-12-10 4 views
2

を返すこれは Safe in C# not in C++, simple return of pointer/reference,C++、オブジェクトポインタ

からのフォローアップの質問はこれですか?

person* NewPerson(void) 
{ 
    person* pp = new person; 

    return pp; //return pointer to person. 
} 

私はワイルドポインタであるため、最初のものは悪い考えです。 2番目のケースでは、オブジェクトはヒープ上で安全ですか?C# のように、最後の参照がなくなったらスコープから外れますか?

+1

いずれもC#コードです。もう1つは手動で解放しないとC++でのメモリリークです。 – CodesInChaos

+0

彼らは同じではなく、どちらも悪い考えです。 –

答えて

2

安全ですが、オブジェクトは戻ってからまだ生きています。

しかし、C++でオブジェクトが自動的にクリーンアップされるとは思わないでください。標準C++にはガベージコレクションはありません。オブジェクトを自分でdeleteにするか、何らかの形のスマートポインタを使用する必要があります。

0

後者は安全です。しかし、C++は(通常)ガベージコレクションを提供しないので、返されたオブジェクトの明示的なdeleteを手配する必要があります。

0

あなたが言うように、最初のケースは、ポインタが有効でないために悪いです。 2番目のケースでは、C++のメモリは管理されていません。あなた自身の後でクリーンアップする必要があります。 C++は通常のポインタ上の参照を追跡しません。つまり、std::shared_ptrが対象です。

1
person* NewPerson(void) 
{ 
    person* pp = new person; 

    return pp; //return pointer to person. 
} 

私はそれが野生 ポインタになりますので、最初のものは、悪い考えであることを知っています。 2番目のケースでは、オブジェクトはヒープ上で安全でしょうか?そして最後の参照がなくなったらC#のような は範囲外になりますか?

最初に修正します:関数が終了すると、そのfunctinのスタック上のデータへのポインタが返され、再利用され、変更されます。

第2の場合:オブジェクトは、実行スタックとは別のヒープ上に作成されます。関数が終了すると、ヒープ上のオブジェクトは安全であり、同じままです。ただし、C++では自動的にガベージコレクションは行われないため、ヒープオブジェクトへの参照がすべて失われた場合、メモリリークが発生します。プログラムが終了するまで、オブジェクトの領域は再利用されません。

3

はい、2番目のケースは安全です。

しかし、呼び出し元には返されたポインタdeleteが必要です。 C++ 11、あなたはstd::shared_ptrstd::unique_ptrを使用できる場合

boost::shared_ptr<person> NewPerson() 
{ 
    boost::shared_ptr<person> pp = boost::make_shared<person>(); 

    return pp; 
} 

:あなたはこのboost::shared_ptrを使用し、それが使用されなくなったときに、それは破壊されませんを変更することができます。

+0

参照されたポインタが0(NULL)に設定されていればOKですか?スコープの外にある、例えばC# – Niklas

+0

のようにスコープが外れた場合、または返されたスマートポインタで 'reset()'を呼び出すことによってNULLに設定されている場合。 – hmjd

関連する問題