2014-10-26 224 views
3

當我的程序結束時,出現「Debug assertion failed」錯誤。我一直在努力解決它很長一段時間,只是找不到原因。即使我在uni的教授說他沒有看錯。所以你是我最後的希望,stackoverowow。請幫忙。調試斷言失敗

程序找到兩個列表的交集,然後檢查第三個列表是否是交集的子集。

錯誤的屏幕截圖:

Here

的代碼:

list.h:

#ifndef __LIST_H_INCLUDED__ 
#define __LIST_H_INCLUDED__ 
#include <string> 
#include <iostream> 
#include <fstream> 

struct node 
{ 
    int value; 
    node *next; 
}; 

class list 
{ 
    node* head; 
public: 
    list(); 
    ~list(); 
    void AddNodes(std::istream &input); 
    void PrintList(std::ostream &output = std::cout); 
    void AddOneNode(int AddVal); 
    node* RetHead(); 
    list* Intersection(list* list2); 
    bool IsPresent(int val); 
    bool Subset(list subset); 
}; 

#endif 

list.cpp:

#include "stdafx.h" 
#include "list.h" 
#include <iostream> 
#include <fstream> 


list::list() 
{ 
    head=NULL; 
} 

list::~list() 
{ 

    node* current = head; 
    while(current != 0) 
    { 
     node* next = current->next; 
     delete current; 
     current = next; 
    } 
    head = 0; 

} 

void list::AddNodes(std::istream &input) 
{ 
    int InVal; 
    while(input>>InVal) 
     AddOneNode(InVal); 
} 

void list::AddOneNode(int AddVal) 
{ 
    node *NewNode= new node; 
    NewNode->value=AddVal; 
    NewNode->next=NULL; 
    if(!head) 
     head=NewNode; 
    else 
     { 
      node *temp=head; 
      while(temp->next) 
       temp=temp->next; 
      temp->next=NewNode; 
     } 
} 

void list::PrintList(std::ostream &output) 
{ 
    node *temp=head; 
    while(temp) 
    { 
     output<<temp->value<<std::endl; 
     temp=temp->next; 

    } 
} 

list* list::Intersection(list *list2) 
{ 
    list* result=new list; 
    node* temp1=head; 
    while(temp1) 
    { 
     if(list2->IsPresent(temp1->value)) 
      result->AddOneNode(temp1->value); 
     temp1=temp1->next; 

    } 
    return result; 
} 

bool list::IsPresent(int val) 
{ 
    node *temp=head; 
    while(temp) 
    { 
     if(temp->value==val) 
      return true; 
     temp=temp->next; 
    } 
    return false; 
} 


bool list::Subset(list subset) // head=set 
{ 
    bool flag; 
    node* tempset=head; 
    node* tempsub=subset.RetHead(); 
    while(tempset) 
    { 
     if (tempsub->value==tempset->value) 
     { 
      flag=true; 
      break; 
     } 
     tempset=tempset->next; 
    } 
    if (!tempset) 
     return false; 
    while(tempsub) 
    { 
     tempsub=tempsub->next; 
     if(!tempsub) 
      return true; 
     while(tempsub->value!=tempset->value&&tempset) 
      tempset=tempset->next; 
     if(!tempset) 
      return false; 
    } 
    return flag; 
} 

node* list::RetHead() 
{ 
    return head; 
} 

main.cpp中:

#include "stdafx.h" 
#include "list.h" 
#include <Windows.h> 
#include <fstream> 

list Cross (list list1, list list2); 
bool Subset (list set, list subset); 

int main() 
{ 
    setlocale (LC_ALL, "Russian"); 
    list l1,l2,l3; 
    std::ifstream fl1 ("l1.txt"); 
    std::ifstream fl2 ("l2.txt"); 
    std::ifstream fl3 ("l3.txt"); 
    l1.AddNodes(fl1); 
    std::cout<<"List 1:"<<std::endl; 
    l1.PrintList(); 
    std::cout<<std::endl; 
    l2.AddNodes(fl2); 
    std::cout<<"List 2:"<<std::endl; 
    l2.PrintList(); 
    std::cout<<std::endl; 
    l3.AddNodes(fl3); 
    std::cout<<"List 3:"<<std::endl; 
    l3.PrintList(); 
    std::cout<<"Intersection of list 1 and list 2"<<std::endl; 
    list *intersec=l1.Intersection(&l2); 
    intersec->PrintList(); 
    std::cout<<std::endl; 
    if(intersec->Subset(l3)) 
     std::cout<<"Third set is a subset of the intersection"<<std::endl; 
    else 
     std::cout<<"Third set is not a subset of the intersection"<<std::endl; 
    system("pause"); 
    return 0; 
} 
+1

您的包含警衛使用[保留標識符](http:// stackoverflow。COM /問題/ 228783 /什麼,是最規則有關,使用安下劃線-IN-A-C-標識符)。你也沒有遵循三條規則(真的,不要使用擁有原始指針)。 – chris 2014-10-26 16:00:32

+0

什麼是您的輸入數據? – 2014-10-26 16:01:59

+0

你很可能會「雙重釋放」某些東西。 – 2014-10-26 16:02:43

回答

7

的問題是,該函數通過list::Subset(list subset)值取它的參數使所述list的副本作出。由於您沒有遵循三條規則(如Chris的評論所述),所以製作了淺拷貝。這意味着list的兩個實例「擁有」指針。當Subset函數返回時,副本超出範圍,導致節點被刪除。當程序退出時,list的原始副本超出了範圍,並且它會嘗試刪除導致斷言的相同節點再次

您可以通過引用而不是按值來引用參數。更改

class list 
{ 
    // ... snip ... 
    bool Subset(list subset); 
    // ... snip ... 
}; 

class list 
{ 
    // ... snip ... 
    bool Subset(list& subset); 
    // ... snip ... 
}; 

bool list::Subset(list subset) 
{ 
    // ... snip ... 
} 

bool list::Subset(list& subset) 
{ 
    // ... snip ... 
} 

其他一些建議:

  1. 要麼執行正確的複製構造函數,要麼聲明一個,並使其成爲私有的,以防止複製
  2. 瞭解const正確性。由於Subset不會修改傳遞給它的列表的內容,您可以改爲聲明它bool list::Subset(const list&) const。這將要求list::RetHead()也被宣佈爲const
  3. bool flag in list::Subset未初始化,表示如果您的邏輯不正確,則可以返回任何值。
+0

非常感謝!現在一切正常。我想現在我必須閱讀3的規則並使用const。 – Ivan 2014-10-26 16:27:59