2017-11-15 13 views
-1

私は次の方法を使用すれば大丈夫ですか?構文エラーと警告はありませんが、私はそこにメモリの問題があることを知りたいですか?次のメモリ割り当ての方法を使用するかどうかは分かりますか?

#include <iostream> 
using namespace std; 

class test { 
    int* x; 
public: 
    test(int *n) { this->x = new int(*n); } 
    inline int get() { return *x; } 
    ~test() { delete x; } 
}; 

int main(void) { 
while(1){ 
    test a(new int(3)); 
    cout << a.get() << endl; 
} 
    return 0; 
} 
+6

あなたは3/5/0のルールに違反しています。 –

+3

'a'作成時にメモリがリークしています – Slava

+0

どうすればルールに違反しないように変更できますか? –

答えて

4

であるあなたは、あなたのコード内の2つの問題があります。

  • をあなたのクラスはa

を作成するときにメモリをリークしている rule of three/five/zero

  • に違反します

    このコードでは:

    test a(new int(3)); 
    

    あなたは、動的に値3でintを割り当て、値を使用して、動的に割り当てられたintを所有しています作成a CTORに渡します。その後、このメモリはリークされます。あなたがクラスに動的に割り当てられたデータを渡したい場合は、スマートポインタを使用します。

    class test { 
        std::unique_ptr<int> x; 
    public: 
        test(std::unique_ptr<int> n) : x(std::move(n)) { } 
        int get() const { return *x; } 
    }; 
    
    int main() 
    { 
        x a(std::make_unique<int>(3)); // since c++14 
        x a(std::unique_ptr<int>(new int(3))); // before c++14 
        ... 
    } 
    

    を、あなたが明示的にデストラクタを実装する必要はありません、あなたはルールに違反していないと、CTORに動的に割り当てられたデータを渡すために安全です。

    注:例としてintを使用したと仮定しましたが、intの1つを動的に割り当てることは役に立たないので、値で保存してください。

  • +0

    コピーコンストラクタを追加し、次のようなコードを変更する場合: 'int * p = new int(3); テストa(p)。 delete p; ' 大丈夫ですか? –

    +0

    @LukaMamulaishviliコピーコンストラクタ*と*代入演算子(3の規則)。両方とも、5つのルールに適合するように、移動セマンティクスもあります。それ以外にも、あなたは正しいでしょう... – Aconcagua

    +0

    @LukaMamulaishviliところで、一時的な配列の場合、別の方法もあります:それをスタックに割り当てます: 'int p [] = {3};テストする(p); '(確かに、必ずしも適切ではないが、もし、...)。 – Aconcagua

    3

    あなたは3のルール(C++ 11以降)に違反しています。つまり、デストラクタを定義してから、コピー/移動コンストラクタ/操作を定義する必要があります。

    あなたの実装では、コピー/移動コンストラクタ/操作が間違っています。あなたのオブジェクトをコピーすると、それはあなたのポインタの浅いコピーを行い、それを削除しますので、あなたはダブル削除します。移動すると、割り当てられていないポインタが削除されます。

    ボーナスポイント:あなたのインラインは役に立たない

    関連する問題