Iva*_*van 3 c++ debugging linked-list
程序结束时,我收到"Debug assertion failed"错误.我一直试图解决它很长一段时间,但却找不到原因.甚至我在大学的教授说他没有看错.所以你是我最后的希望,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
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
问题是该函数list::Subset(list subset)
通过值获取其参数,从而导致生成副本list
.由于您没有遵循三条规则(如Chris的评论中所述),因此制作了一份浅层副本.这意味着两个list
"拥有"指针的实例.当Subset
函数返回时,副本超出范围,导致节点被删除.当程序退出list
超出范围的原始副本时,它会尝试再次删除相同的节点,从而导致断言.
您可以通过引用而不是值来获取参数.更改
class list
{
// ... snip ...
bool Subset(list subset);
// ... snip ...
};
Run Code Online (Sandbox Code Playgroud)
至
class list
{
// ... snip ...
bool Subset(list& subset);
// ... snip ...
};
Run Code Online (Sandbox Code Playgroud)
和
bool list::Subset(list subset)
{
// ... snip ...
}
Run Code Online (Sandbox Code Playgroud)
至
bool list::Subset(list& subset)
{
// ... snip ...
}
Run Code Online (Sandbox Code Playgroud)
其他一些建议:
const
正确性.由于Subset
不会修改传递给它的列表的内容,因此您可以声明它bool list::Subset(const list&) const
.这也需要list::RetHead()
声明const
.bool flag
in list::Subset
未初始化意味着如果逻辑不正确,则可以返回任何值.