2014-10-26 232 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