[解決済み] new'を使うとなぜメモリリークが起こるのか?
質問
私はC#を最初に学び、今はC++を始めています。私が理解しているように、演算子
new
はC#のものと似て非なるものです。
このサンプルコードでメモリリークが発生した理由を説明してください。
class A { ... };
struct B { ... };
A *object1 = new A();
B object2 = *(new B());
どのように解決するのですか?
何が起きているのか
と書くと
T t;
と書くと
T
と
自動保存期間
. スコープ外になると自動的にクリーンアップされます。
と書くと
new T()
と書くと
T
と
動的な保存期間
. 自動的にクリーンアップされることはありません。
にそのポインタを渡す必要があります。
delete
にポインタを渡す必要があります。
しかし、2番目の例はもっと悪いです。ポインタを再参照して、オブジェクトのコピーを作っているのです。この方法では
new
で作成されたオブジェクトへのポインタを失ってしまうので、削除したくてもできないのです!
やるべきこと
ストレージの自動継続を選択すべきです。新しいオブジェクトが必要な場合は、ただ書き込むだけです。
A a; // a new object of type A
B b; // a new object of type B
動的な保存期間が必要な場合は、割り当てられたオブジェクトへのポインタを、自動的に削除する自動保存期間オブジェクトに保存してください。
template <typename T>
class automatic_pointer {
public:
automatic_pointer(T* pointer) : pointer(pointer) {}
// destructor: gets called upon cleanup
// in this case, we want to use delete
~automatic_pointer() { delete pointer; }
// emulate pointers!
// with this we can write *p
T& operator*() const { return *pointer; }
// and with this we can write p->f()
T* operator->() const { return pointer; }
private:
T* pointer;
// for this example, I'll just forbid copies
// a smarter class could deal with this some other way
automatic_pointer(automatic_pointer const&);
automatic_pointer& operator=(automatic_pointer const&);
};
automatic_pointer<A> a(new A()); // acts like a pointer, but deletes automatically
automatic_pointer<B> b(new B()); // acts like a pointer, but deletes automatically
<イグ
これは一般的なイディオムで、RAIIというあまり説明的でない名前で呼ばれています( リソースの取得は初期化 ). クリーンアップが必要なリソースを取得したとき、それを自動保存期間のオブジェクトに貼り付けるので、クリーンアップについて心配する必要はありません。これは、メモリ、開いているファイル、ネットワーク接続など、どんなリソースにも当てはまります。
これは
automatic_pointer
のようなものは既に様々な形で存在しています。私はただ例を示すためにこれを提供しました。非常によく似たクラスが標準ライブラリに存在し
std::unique_ptr
.
という古いもの(C++11以前)もあります。
auto_ptr
という名前の古いものもありますが、これは奇妙なコピー動作があるため、現在では非推奨となっています。
そして、さらにスマートな例として、例えば
std::shared_ptr
のように、同じオブジェクトへの複数のポインタを許可し、最後のポインタが破壊されたときだけそれをクリーンアップするような、さらに賢い例もあります。
関連
-
[解決済み] 既に.objで定義されている-二重包含はない
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] なぜテンプレートはヘッダーファイルでしか実装できないのですか?
-
[解決済み] JavaScriptの「new」キーワードとは何ですか?
-
[解決済み] なぜ、オブジェクトそのものではなく、ポインタを使用しなければならないのですか?
-
[解決済み] performSelectorのセレクタが不明なため、リークが発生する可能性があります。
-
[解決済み] 型名の後の括弧は、newで違いがあるのでしょうか?
-
[解決済み】なぜC++プログラマは'new'の使用を最小限に抑えなければならないのでしょうか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み】C++ 式はポインタからオブジェクトへの型を持っている必要があります。
-
[解決済み】抽象クラス型の無効なnew-expression
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み】C++エラー:の初期化に一致するコンストラクタがありません。
-
[解決済み】浮動小数点例外エラーが発生する: 8
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】Visual Studio 2013および2015でC++コンパイラーエラーC2280「削除された関数を参照しようとした」が発生する
-
[解決済み] クラスのインスタンスを作成する