2014-10-17 358 views
0

我知道一個double free或者corrupt錯誤通常是違反了big 3,但是在這種情況下,我找不到違規發生的地方。我有一個拷貝構造函數,析構函數和任何處理指針的賦值操作符。double free or corruption(out)C++

在我這裏的.h是我的類實現:

class BST 
{ 
public: 
    struct SequenceMap{ 
     std::string astring; 
     std::vector<std::string> sequences; 

     //void setValue(std::string theString, std::string anotherString); 
     SequenceMap& operator=(const SequenceMap map); 

     void setValue(std::string theString, std::string anotherString); 

     SequenceMap(); //constructor no copy since no pointers 
     ~SequenceMap(); 
    }; 
    struct BinaryNode{ 
     SequenceMap item; 
     BinaryNode *left; 
     BinaryNode *right; 
     BinaryNode(SequenceMap i); //constructor 

     inline bool operator> (std::string t); 
     inline bool operator< (std::string t); 

     BinaryNode& operator=(const BinaryNode node) ; 
     ~BinaryNode(); 
     BinaryNode(const BinaryNode &otherNode); 
    }; 
    BinaryNode *root; 
    int insert(SequenceMap &x, BinaryNode *&t, bool &ifdup); 

    BST(); 
    ~BST(); 
    void BSTClear(BST::BinaryNode *t); 
    BST(const BST &otherTree); 

    BST& operator=(const BST tree); 
}; 

我實現我的構造函數,析構函數和賦值運算符在我的.cpp:

BST::SequenceMap& BST::SequenceMap::operator=(const BST::SequenceMap map) 
{ 
    astring = map.astring; 
    sequences = map.sequences; 
    return *this; 
} 

inline bool BST::BinaryNode::operator<(std::string t){//does compare} 
inline bool BST::BinaryNode::operator>(std::string t){//does compare} 

BST::BinaryNode& BST::BinaryNode::operator=(const BST::BinaryNode node) 
{ 
    item = node.item; 
    if(node.left != nullptr) 
     left = new BST::BinaryNode(node.left->item); 
    else 
     left = nullptr; 
    if(node.right != nullptr) 
     right = new BST::BinaryNode(node.right->item); 
    else 
     right = nullptr; 

    return *this; 
} 
BST& BST::operator=(const BST tree){root = new BinaryNode(tree.root);} 

BST::BinaryNode::BinaryNode(const BST::BinaryNode &otherNode){ 
    item = otherNode.item; 
    if(otherNode.left != nullptr) 
     left = new BST::BinaryNode(otherNode.left->item); 
    else 
     left = nullptr; 
    if(otherNode.right != nullptr) 
     right = new BST::BinaryNode(otherNode.right->item); 
    else 
     right = nullptr; 
} 

BST::BinaryNode::BinaryNode(SequenceMap i){ item = i; left = nullptr; right = nullptr; } 
BST::BinaryNode::~BinaryNode(){ delete &item; left = nullptr; right = nullptr; } 

BST::BST(){root = nullptr;} 
BST::BST(const BST &otherTree){root = new BinaryNode(otherTree.root->item);} 
BST::~BST(){BSTClear(root);} 

BST::SequenceMap::SequenceMap(){astring = "";} 
BST::SequenceMap::~SequenceMap(){ delete &astring; delete &sequences;} 

void BST::BSTClear(BST::BinaryNode*t){ 
    if(t->left != nullptr) 
     BSTClear(t->left); 
    if(t->right != nullptr) 
     BSTClear(t->right);  
    delete t; 
} 

我以前cout來測試,其中錯誤發生,當我在指定行的main.cpp中執行此操作時發生錯誤:

while(getline(sequences,sequence) && getline(enzymes,enzyme)) 
{ 
    BST::SequenceMap map = BST::SequenceMap; 
    map->setValue(sequence, enzyme); 

    sequenceTree->insert(map, sequenceTree->root, dup); //ON THIS LINE 
} 

,並在我的.cpp我插入功能:

int BST::insert(BST::SequenceMap &x, BST::BinaryNode *&t, bool &ifdup) 
{ 
    if(t == nullptr) 
    { 
     //std::cout<<"2"<<std::endl;    
     t = new BST::BinaryNode(x); //ON THIS LINE 
     //std::cout<<"1"<<std::endl; 
    } 
    //do more things 
} 

我不知道,如果這被認爲是MSCV,但我這是我需要重現我的錯誤最少。 Stack Trace

+1

使用的valgrind或調試器來查明問題。至少你應該能夠在你的問題中包含堆棧跟蹤。 – 2014-10-17 02:52:23

+0

@JohnZwinck有沒有兼容Windows和C++ 11的兼容?我沒有訪問Linux機器atm – SemicolonExpected 2014-10-17 02:53:57

+0

您還沒有包含BinaryNode構造函數。 – 2014-10-17 02:55:01

回答

3

考慮您的BinaryNode賦值運算符。

BST::BinaryNode& BST::BinaryNode::operator=(const BST::BinaryNode node) 
{ 
    item = node.item; 
    if(node.left != nullptr) 
     left = node.left; 
    else 
     left = nullptr; 
    if(node.right != nullptr) 
     right = node.right; 
    else 
     right = nullptr; 

    return *this; 
} 

下,仍然以他們的leftright指針指向同一件事BinaryNode的兩個實例。當兩個實例的析構函數被調用時,它們將釋放指針並導致一個雙重空閒。

你需要做什麼是由leftright指針,而不是指針實際上使一個新的副本指出,或有某種形式的引用計數指針。

另外請注意:你如果測試不增加任何價值,你只是分配nullptr如果原始值是nullptr

+0

我會如何深入複製這個?它是否必須像'left = new BST :: BinaryNode(left-> item)',並且會遞歸地創建一個與第一個相同的新的「子樹」或將不起作用? – SemicolonExpected 2014-10-17 03:16:26

+1

是的,那是對的。如果你的拷貝構造函數不是'nullptr',你需要做的就是遞歸地調用自己的'left'和'right'節點。幸運的是,你已經有了你需要的測試:) – 2014-10-17 03:31:43

+0

其實你想'left = BST :: BinaryNode(node.left)',所以你調用了複製構造函數。 – 2014-10-17 03:34:14