我得到"调试断言失败"我的程序结束时出错。我一直在努力修复它并且无法找到原因。甚至我在大学的教授说他没有看错。所以你是我最后的希望,stackoverllow。请帮忙。
程序找到两个列表的交集,然后检查第三个列表是否是交集的子集。
错误的屏幕截图:
代码:
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;
}
答案 0 :(得分: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 ...
}
其他一些建议:
const
正确性。由于Subset
不会修改传递给它的列表的内容,因此您可以将其声明为bool list::Subset(const list&) const
。这也需要list::RetHead()
声明const
。bool flag
中的list::Subset
未初始化,这意味着如果您的逻辑不正确,则可以返回任何值。