インテリジェントポインタについて

2916 ワード

newとdeleteを使用して、ダイナミックメモリでよく発生するエラーを管理します.
1.deleteを忘れた場合、「メモリ漏れ」が発生します.
2.野ポインタ.オブジェクトが解放された後、(ここで注意すると、このときのポインタは、かつて存在していたオブジェクトを指す懸垂ポインタとなっているが、そのオブジェクトはもう存在しない.結果は定義されておらず、検出が困難である.)このとき、私たちが再び使用すると、不正に内蔵されたポインタが発生する.
ただし、ポインタを保持する必要がある場合は、delete以降にnullptrをポインタに割り当てることができます.これにより、ポインタは次のコードで任意のオブジェクトを指しません.
auto p(new auto 42);
auto q = p;
delete p;
p = nullptr;

余談:この問題をテストする時、私はqの値を出力してまだ42で、しかも間違いを報告していないことを発見して、それからdelete pの後で、私はまた*p=19をあげます;このときp,qの値は出力時ともに19であり,エラーも報告されていない.このコードは実は根本的に間違っています.p,qにはもう有効なメモリ容量がありませんから.ここではメモリが解放されていますが、ポインタの値は変わらず、指向するメモリは0をクリアできません.指向するこのメモリ領域は割り当てられています.他のデータに上書きされていなければ、幸いにも出力できます.これは、あなたが割り当てたメモリが小さく、割り当てを継続していないため、占有される確率が小さいためです.私が使っているxcodeは、VSに変えて正常にエラーを報告したのは、VSがコンパイラの観点からバッファオーバーフローなどの問題を解決するために、加えたこの機能に加えて、C++標準にはこのような要求はなく、すべてのxcodeとgccはチェックしません.そこでここでは純粋なC++コードを書くときにvsを使うことをお勧めします.
3.deleteを繰り返すと自由空間が破壊される
インテリジェントポインタと一般ポインタの違いは、インテリジェントポインタが実際には一般ポインタにパッケージメカニズムを追加していることであり、このようなパッケージメカニズムの目的は、インテリジェントポインタがオブジェクトのライフサイクルを容易に管理できるようにすることである.C++では、通常のポインタを使用してオブジェクトを指すポインタを作成する場合、このオブジェクトを使用した後、自分で削除する必要があることを知っています.たとえば、次のようにします.
ObjectType* temp_ptr = new ObjectType();
temp_ptr->foo();
delete temp_ptr;

プログラマーがtempを呼び出すのを忘れた場合、多くの資料で指摘されています.ptr後にtemp_を削除ptrは、サスペンションポインタ(dangling pointer)をもたらします.つまり、このポインタが現在指しているメモリ領域は、コンテンツプログラマーが把握して制御できないため、メモリの漏洩を招きやすい可能性があります.しかし、実際には「忘れる」だけでなく、上記のプログラムでfoo()が実行時に異常を投げ出すとtemp_ptrが指すオブジェクトは安全に削除されません.このとき,インテリジェントポインタの出現は実際にはオブジェクトのライフサイクルを容易に制御するためであり,インテリジェントポインタでは,1つのオブジェクトがいつ,どのような条件で解析されるか,あるいは削除されるかはインテリジェントポインタ自体によって決定され,ユーザは管理する必要はない.
スマートポインタというものが現れました
スマートポインタ(英語:Smart pointer)は抽象的なデータ型です.プログラム設計では、通常、クラステンプレート(class template)によって実装され、テンプレート(template)によって汎用化され、通常、クラス(class)の構造関数によって自動解放ポインタが指すメモリまたはオブジェクトを達成する.(ウィキペディア)
C++  スマートポインタauto_は3種類ありますptr、unique_ptrとshared_ptr,weak_ptr.
unique_の場合ptr
C++11にはstd::unique_ptrが提供され、<memory>ヘッダファイルに定義されている.
C++11はmoveの意味を追加し、copyの意味よりも値伝達をよりよく実現することができる.std::auto_ptrはcopyの意味を使用し、前方互換性のため、C++11はstd::auto_を修正していない.ptrは、moveの意味を用いるstd::unique_ptrを新たに導入する.
uniqu_ptrのコピー構造関数および付与演算子はdeletedとして宣言されます.すなわち、コピーできません.std::moveでのみ、メモリの所有権を転送できます.すなわち,右値であれば他のオブジェクトに値を割り当てることができ,他の存在時間の長いオブジェクトはコピーできず,c 11 moveの意味でメモリ所有権の伝達しか実現できない.
またshared_についてはptrとweak_ptr std::shared_ptrは参照カウントを使用するため、ループカウントの問題がある.サイクルを破るためにstd::weak_ptrを使うことができます.その名の通り、weak_ptrは弱い参照であり、参照のみであり、カウントされない.メモリがshared_された場合ptrとweak_ptrは同時に参照し、すべてのshared_がptrが析出した後、まだweakがあるかどうかにかかわらずptrはこのメモリを参照し、メモリも解放されます.したがって、weak_ptrは、メモリが有効であることを保証せず、使用前にチェックする必要があります.
参照先:
1:@知乎胡昊 リンク:https://www.zhihu.com/question/20368881/answer/14918675
2:ウィキペディア:https://zh.wikipedia.org/wiki/%E6%99%BA%E8%83%BD%E6%8C%87%E9%92%88