-1

HashMapを実装しています。コピーコンストラクタと代入演算子のオーバーロード関数があります。再ハッシングがHashMapで発生すると、代入演算子のオーバーロード関数はセグメンテーション違反をスローします。しかし、再ハッシングが発生しなければ代入演算子は正常に動作します。私はあまりにも長い間コードを見ていたかもしれないと思うし、コードをスキャンする新しい目のセットが問題を明らかにするならば。ここでハッシュ関数で再ハッシングが発生した場合、代入演算子のオーバーロードが機能しません。

おかげ

は私の主なメンバ関数です:ここ

HashMap::HashMap() 
    :hasher{hash}, Buckets_Array{new Node* [initialBucketCount]}, currentBucketCount{initialBucketCount}, sz{0} 

{ 
    fillArray(Buckets_Array, currentBucketCount); 


} 


HashMap::HashMap(const HashMap& hm) 
    :hasher{hm.hasher}, Buckets_Array{new Node*[hm.currentBucketCount]},currentBucketCount{hm.currentBucketCount}, sz{hm.sz} 
{ 
    arrayCopy(hm.Buckets_Array, Buckets_Array, currentBucketCount); 

} 


HashMap::~HashMap() 
{ 
    for(int i = 0; i < currentBucketCount; i++) 
    { 
     deleteLinkedList(Buckets_Array[i]); 
    } 

    delete[] Buckets_Array; 
} 


HashMap& HashMap::operator=(const HashMap& hm) 
{ 

    if (this != &hm) 
    { 

     Node** newNodeArray = new Node*[hm.currentBucketCount]; 

     fillArray(newNodeArray, hm.currentBucketCount); 

     arrayCopy(hm.Buckets_Array, newNodeArray, currentBucketCount); 
     currentBucketCount = hm.currentBucketCount; 
     sz = hm.sz; 

     for (int i = 0; i < currentBucketCount; i++) 
     { 
      deleteLinkedList(Buckets_Array[i]); 
     } 

     delete[] Buckets_Array; 
     Buckets_Array = newNodeArray; 

    } 

    return *this; 
} 

void HashMap::add(const std::string& key, const std::string& value) 
{ 
    // REHASH IF EXCEEDED LOAD FACTOR 
    double futureLoadFactor = double((sz + 1))/double(currentBucketCount); 

    if (futureLoadFactor > maximumLoadFactor) 
    { 
     rehashKeys(); 
    } 

    unsigned int index = getIndex(key); 

    if (!checkExists(Buckets_Array[index], key, value)) 
    { 

     if (Buckets_Array[index] == nullptr) 
     { 
      Node* n = new Node; 
      n->key = key; 
      n->value = value; 
      n->next = nullptr; 
      Buckets_Array[index] = n; 
     } 

     else 
     { 

      addToEnd(Buckets_Array[index], key, value); 

     } 

     sz += 1; 
    } 


} 

は、私が使用するいくつかのヘルパーのメンバ関数です:私はmemcheck実行したとき

void HashMap::fillArray(Node** nodeArray, int size) 
{ 
    for (int i = 0; i < size; i++) 
    { 
     nodeArray[i] = nullptr; 
    } 
} 

void HashMap::rehashKeys() 
{ 
    currentBucketCount = (currentBucketCount * 2) + 1; 
    Node** tempBucketsArry = new Node* [currentBucketCount]; 
    fillArray(tempBucketsArry, currentBucketCount); 

    std::cout << "MAX INDEX: " << currentBucketCount/2 << std::endl; 
    for (int i = 0; i < currentBucketCount/2; i++) 
    { 
     hashLinkedList(Buckets_Array[i], tempBucketsArry); 
     deleteLinkedList(Buckets_Array[i]); 

    } 
    delete[] Buckets_Array; 
    Buckets_Array = tempBucketsArry; 

} 


void HashMap::hashLinkedList(Node* node, Node**& node_arry) 
{ 
    if (node != nullptr) 
    { 
     int newIndex = getIndex(node->key);   
     addToEnd(node_arry[newIndex], node->key, node->value); 
     hashLinkedList(node->next, node_arry); 

    } 
} 

void HashMap::copyNode(Node* sourceNode, Node* targetNode) 
{ 


    targetNode->key = sourceNode->key; 
    targetNode->value = sourceNode->value; 
    sourceNode = sourceNode->next; 

    while (sourceNode != nullptr) 
    { 
     Node* tempNode = new Node; 
     tempNode->key = sourceNode->key; 
     tempNode->value = sourceNode->value; 
     targetNode->next = tempNode; 
     targetNode = targetNode->next; 
     sourceNode = sourceNode->next; 

    } 

    targetNode->next = nullptr; 

} 



void HashMap::arrayCopy(Node** source, Node**& target, int arrysz) 
{ 

    for (int i = 0; i < arrysz; i++) 
    { 
     if (source[i] != nullptr) 
     { 

      Node* copy = new Node; 
      copyNode(source[i], copy); 
      target[i] = copy; 
     } 

     else 
     { 
      target[i] = nullptr; 
     } 
    } 


} 

void HashMap::deleteLinkedList(Node* node) 
{ 




    while (node != nullptr) 
    { 
     if (node->next == nullptr) 
     { 
      delete node; 
      break; 

     } 

     else 
     { 
      Node* next = node->next; 
      delete node; 
      node = next; 
     } 
    } 

} 

// Adds node to the end of linked list 

void HashMap::addToEnd(Node*& node, std::string key, std::string value) 
{ 

    if (node == nullptr) 
    { 
     Node* n = new Node; 
     n->key = key; 
     n->value = value; 
     n->next = nullptr; 
     node = n; 

    } 


    else 
    { 

     addToEnd(node->next, key, value); 

    } 

} 

それが誤りであることを言いましたdeleteLinkedList関数の次の行にあります。

if (node->next == nullptr) 

再ハッシングが発生した場合にのみ問題が発生するため、再ハッシュ関数を確認する傾向が強くなりましたが、代入演算子のオーバーロードされたメソッドを呼び出さないと再ハッシング関数はうまく動作します。私は本当に助けていただければ幸いです。

ありがとうございます。

+0

によってによって置換されます、 'hm.Buckets_Array'のサイズは' hm.currentBucketCount'ですが、 'this-> currentBuck etCount'(これは私が想定しているものとは異なるかもしれません)を 'arrayCopy'に置き換えます。同様に、 'deleteLinkedList()'を呼び出すループは 'hm.currentBucketCount'回を実行します。これは' this-> Buckets_Array'の実際のサイズと等しくないかもしれません。 –

答えて

0

HashMap& HashMap::operator=(const HashMap& hm)には、arrayCopyを呼び出す前にthis->currentBucketCounthm.currentBucketCountを割り当てています。

あなたは両方のステートメントを交換し、deleteLinkedListを呼び出すためにcurrentBucketCountの古い値を維持する必要があります:

arrayCopy(hm.Buckets_Array, newNodeArray, currentBucketCount); 
    currentBucketCount = hm.currentBucketCount; 

トップオフ

int oldBucketCount = currentBucketCount; 
    currentBucketCount = hm.currentBucketCount; 
    arrayCopy(hm.Buckets_Array, newNodeArray, currentBucketCount); 
    ... 
    for (int i = 0; i < oldBucketCount; i++) 
    { 
     deleteLinkedList(Buckets_Array[i]); 
    } 

または

arrayCopy(hm.Buckets_Array, newNodeArray, hm.currentBucketCount); 
    // currentBucketCount = hm.currentBucketCount; 
    // sh = hm.sz; 
    for (int i = 0; i < currentBucketCount; i++) 
    { 
     deleteLinkedList(Buckets_Array[i]); 
    } 
    currentBucketCount = hm.currentBucketCount; 
    sh = hm.sz; 
+1

'deleteLinkedList'ループでは役に立ちません。 –

+0

@IgorTandetnikはい、あなたは完全に正しいです。私は自分の答えを更新する。お返事ありがとうございます。 – Franck

+0

ありがとうございました!ありがとうございました!ありがとうございました!それはあなたを得る小さなものです。 –

関連する問題