2017-02-12 3 views
1

まず、この質問は申し訳ありません。私は、C++でdeletenewに関連する主要な回答のほとんどを見てきましたが、ここでも私の問題を解決することはできません。 ここでは、次のように私は3つのクラスがあります。C++での削除の適切な使用

class bucket 
{ 
    // Some stl container here where data would be inserted 
    // Some methods and fields here 
    // This class has no new keyword 
}; 

class TrieNode 
{ 
    public: 
    bucket *pointer; 
    TrieNode() //Constructor for this class 
    { 
     pointer = NULL; 
    }; 
    TrieNode(int local) //Parametrized Constructor for this class 
    { 
     pointer = new bucket(local); //Here is the new keyword 
    } 
}; 

class Hashtable 
{ 
    private: 
    int globalDepth; 
    std::vector<TrieNode> table; //Vector of other class 

    void Split(int index) 
    { 
    // Here I am creating instances of other class(TrieNode) which has pointer 
     TrieNode first(capacity); 
     TrieNode second(capacity); 
    // Then after some processing I have to do this 
     table[index] = first; //Assignment which will be using new keyword in it's class i.e. first 
     table[mirrorIndex] = second; //again assignment 
    } 
public: 
    Hashtable(int globalDepth) //Constructor for this class 
    { 
     std::cout<<"Table is being created...\n"; 
     this->globalDepth = globalDepth; 
     table.resize(pow(2,globalDepth),TrieNode()); //vector of class here 
    } 
}; 

int main(int argc, char const *argv[]) 
{ 
    bool input = true; 
    Hashtable mytable(1); //Instance of Third class 
} 

今私の問題は、私はdelete pointerとクラスTrieNodeでデストラクタを使用する場合、それは私はできるだけ早く私は、クラスCのベクトルで何かを挿入しようとして、障害をセグメンテーションを示していますデストラクタは作成後に自動的に呼び出され、ベクタ[right?]が削除され、クラスCデストラクタでdeleteを使用した場合、delete table[i].pointerとしてエラーが発生します。だから、どうすればdeleteを使うべきですか?たとえば、私がクラスインスタンスのいくつかの関数の中での(新しい)の割り当てを使用したケース。クラスCの上のスプリット関数で、ここで全体のスタイルを変更する必要がありますか?あなたが能力を定義しなかった

+1

gdbの使い方を学び、std :: unique_ptrとコピーコンストラクタ(実際にコピーしたもの)について読む。 – James

+0

@James確かに。ありがとう! –

答えて

0
class TrieNode 
{ 
    public: 
    bucket *pointer; 
    TrieNode() //Constructor for this class 
    { 
     pointer = NULL; 
    } 
    ~TrieNode() //destructor for this class 
    { 
     pointer = NULL; 
delete pointer; 
    } 
    TrieNode(int local) //Parametrized Constructor for this class 
    { 
     pointer = new bucket(local); //Here is the new keyword 
    } 
}; 

? ';'があります。私が削除したコンストラクタの定義の後。 クラスのデストラクタは、単にヒープに割り当てられたオブジェクトを新しいもので削除する必要があります。コンパイラはすべてのローカル変数を破棄し、割り当てられたヒープについて心配します。クラスのメンバとして、指定されたクラスのメンバを使用して、関数の引数は悪い習慣であるように、両方のまったく同じ名前の変数を持つ

Hashtable(int nGlobalDepth) //Constructor for this class 
    { 
     std::cout<<"Table is being created...\n"; 
     this->globalDepth = nGlobalDepth; 
     table.resize(pow(2,globalDepth),TrieNode()); //vector of class here 
    } 

、あなたはいくつかのオプションを持っている(クラスのメンバ変数に「_」接頭辞を使用することができますまたは引数の名前を変更)

+0

私はすべてのクラスとメソッドの完全なコードを示していません。 'capacity 'はメソッド内で定義された' int'です。私はこのコードをチェックし、私が完了するとすぐに返信します。方法と1つの質問をお寄せいただきありがとうございます。なぜあなたは 'ポインタのNULL 'を作成し、それを'削除'していますか?それはどんな目的に役立ちますか? –

+0

@SunilKumar削除する前にポインタをヌルにするとエラーが発生する – James

+0

TrieNodeは3のルールに従っていないため、 –

1

TrieNodeインスタンスは、タイプbucketのそのpointerインスタンスを所有しているので、デストラクタでdeleteを呼び出すことによって、それを解放する責任があります。

~TrieNode() 
{ 
    delete pointer; 
} 

(それはそのタイプではなく、その使用方法を示していることから、pointerはおそらく変数のための偉大な名前ではないことに注意してくださいdataか何かを考えてみましょう。。)

:だから最初のあなたのような何かを追加する必要があります

TrieNodeが削除されると、そのバケットポインタも削除されます。 deletenullptrに安全に呼び出すことができ、何もしないので、pointerが設定されているかどうかをテストする必要はありません。

ハッシュテーブルはのインスタンスを使用するため、ベクトルにはオブジェクトインスタンスが含まれ(所有する)ことになります。したがって、インスタンスを削除して、HashTableなどを削除すると、すべて正しくクリーンアップする必要があります。

TrieNodeのインスタンスを作成してHashTableに渡すと、潜在的な問題が発生する可能性があります。コピーコンストラクタを定義していないので、オブジェクトの浅いコピーが作成されるため、ヒープ上の同じバケットを指す2つのオブジェクトが作成されます。最初のインスタンスが破棄されると、バケットは削除されます。しかし、2番目のインスタンスが破棄されると、同様に2回目のバケットの削除を試み、クラッシュを引き起こします。私はこれがあなたが説明するクラッシュする問題を説明していると思う。

一般に、クラスがメモリを動的に割り当てる場合、メモリが正しく管理されるようにデストラクタとコピーコンストラクタが必要です。新しく/削除する作業を対称的に行うようにしてください。メモリを所有するもの(new)もdeleteです。ハッシュテーブルは、トライオブジェクトに「到達」して、その代わりにメモリを削除してはなりません。

@Jamesが上でコメントしたように、スマートポインタを使用して、コンパイラとライブラリがあなたのために仕事をする価値があります。

関連する問題