2014-10-26 4 views
3

Я получаю сообщение об ошибке «Ошибка отладки» при завершении моей программы. Я пытался исправить это в течение длительного времени и просто не могу найти причину. Даже мой профессор в университете сказал, что не видит ничего плохого. Итак, ты моя последняя надежда, stackoverllow. Пожалуйста помоги.Ошибка отладки

Программа находит пересечение двух списков и затем проверяет, является ли третий список подмножеством пересечения.

Скриншот ошибки:

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.ком/вопросы/228783/что-это-The-правила-о-с использованием-ан-подчеркивание-в-а-с-идентификатора). Вы также не следуете правилу из трех (на самом деле, не используйте собственные исходные указатели). – chris

+0

Каковы ваши исходные данные? –

+0

Вы, скорее всего, «дважды освобождаете» что-то. –

ответ

7

Проблема заключается в том, что функция list::Subset(list subset) принимает аргумент по значению вызывает копию list быть сделаны. Поскольку вы не соблюдали правило трех (как отмечено в комментарии Криса), делается мелкой копии. Это означает, что два экземпляра 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 в list::Subset не инициализирован, что означает, что любое значение может быть возвращено, если ваша логика неверна.
+0

Большое спасибо! Сейчас все работает отлично. Думаю, теперь мне нужно будет прочитать правило 3 и использовать константы. – Ivan

Смежные вопросы