2014-04-15 4 views
3

Я использую шаблоны в C++ для создания связанного списка. Я закодировал несколько функций, но удаление узла (либо из головы/хвоста) не работает должным образом. Он отображает ошибку и завершается. При отладке «это», отображаемое в окнах часов, содержит голова, которая равна нулю, и я не знаю, почему. Вот мой код:Удаление узлов в связанном списке не работает?

SLlistSc.h

#ifndef SLlistSc_H 
#define SLlistSc_H 

#include<iostream> 
using namespace std; 

template<class T> class SLlist; 

template <class T> class snode{ 
    friend class SLlist<T>; 
private: 
    T info; 
    snode<T> *next; 
public: 
    inline T getter() const { return info; } 
    inline void setter(T setValue){ info = setValue; } 
    snode(){ info = 0; next = 0; } 
    snode(T inf , snode *nex = 0){ info = inf; next = nex; } 
    ~snode(){ delete next; } 

}; 
template <class T> class SLlist{ 
private: 
    snode<T> *head, *tail; 
    static int total; 
public: 
    SLlist(){ head = tail = 0; } 

    ~SLlist(){ 
     snode<T> *p = head; 
     while (head != 0){ 
      head = head->next; 
      delete p; 
      p = head; 
     } 
    } 
    inline void incrcnt(){ total++; } 
    inline void decrcnt(){ total--; } 
    void displayList(); 
    void addToHead(T inf); 
    void addToTail(T inf); 
    T deleteFromHead(); 
    T deleteFromTail(); 
    int returnIndex(); 
    void deleteInfo(); 
    void deleteAll(); 
}; 

template <class T> void SLlist<T>::displayList(){ 
    snode<T> *p = head; 
    while (p != 0){ 
     cout << "\n->" << p->info; 
     p = p->next; 
    } 
    return; 
} 

template <class T> void SLlist<T>::addToHead(T inf){ 
    snode<T> *temp = new snode<T>(inf, 0); 
    if (head == 0){ head = tail = temp; temp = 0; delete temp; incrcnt(); return; } 
    else { temp->next = head; head = temp; temp = 0; delete temp; incrcnt(); return; } 
} 

template <class T> void SLlist<T>::addToTail(T inf){ 
    snode<T> *temp = new snode<T>(inf, 0); 
    if (head == 0){ head = tail = temp; temp = 0; delete temp; incrcnt(); return; } 
    else{ tail->next = temp; tail = temp; temp = 0; delete temp; return; } 
} 

template <class T> T SLlist<T>::deleteFromHead(){ 
    if (head == 0){ cout << "\nList is already empty"; return (T)0; } 
    if (head == tail){ delete head; head = tail = 0; T info = head->info; return info; } 
    else { 
     T info = head->info; 
     snode<T> *temp = head; 
     head = head->next; 
     temp = 0; 
     delete temp; 
     return info; 
    } 
} 

template <class T> T SLlist<T>::deleteFromTail(){ 
    if (head == 0){ cout << "\nList is already empty"; return (T)0; } 
    if (head == tail){ delete head; head = tail = 0; T info = head->info; return info; } 
    else { 
     T info = tail->info; 
     snode<T> *temp = head; 
     while (temp != 0) 
     { 
      temp = tail; 
     } 
     delete tail; 
     tail = temp; 
     temp = 0; delete temp; 
     return (T)info; 
    } 
} 

#endif 

и файл CPP: SLlistSc.cpp

// SLlistSc.cpp : Defines the entry point for the console application. 
// 

#include"SLlistSc.h" 
#include<iostream> 
using namespace std; 

template <class T> int SLlist<T>::total = 0; 

void main() 
{ 
    cout << "\t\t\t Singly Linked List Super Class Implementation"; 
    SLlist<int> List1; 
    int userchoice=0, inf=0; 
    do{ 
     cout << "\n\n\t\t Menu" 
      << "\n\t1. Display List" 
      << "\n\t2. Add to Head" 
      << "\n\t3. Add to tail" 
      << "\n\t4. Delete from Head" 
      << "\n\t5. Delete from Tail" 
      << "\n\t6. Exit"; 
     cin >> userchoice; 

     switch (userchoice){ 
     case 1: List1.displayList(); break; 
     case 2: cout << "\nEnter info to be added:"; 
       cin >> inf; 
       List1.addToHead(inf); break; 
     case 3: cout << "\nEnter info to be added:"; 
       cin >> inf; 
       List1.addToTail(inf); break; 
     case 4: inf = List1.deleteFromHead(); 
       cout << "\n Value" << inf << "deleted from list"; break; 
     case 5: inf = List1.deleteFromTail(); 
       cout << "\n Value" << inf << "deleted from list"; break; 
     case 6: cout << "\n\t\t\t\tExiting"; 
       exit(0); 
     default: continue; 
     } 
    } while (userchoice < 4); 
} 

Другое дело, я хотел бы спросить, когда мы используем шаблоны на классе (например, класс А), мы должны заменить А на А всюду. Это потому, что компилятор генерирует новый класс, т.е.

<T> разве = A.

И в то время как с помощью друга класса SLlist внутри класса snode, почему я должен заявить следующее:

template<class T> class SLlist; 

перед классом snode ? почему не могу я объявляю его непосредственно в классе snode как:

friend class SLlist<T>; 

Кроме того, если есть шанс improvemet в моем коде, пожалуйста, идти тяжело на меня. Благодарю.

+0

* Он отображает сообщение об ошибке и завершает * - какова ошибка? –

+0

«Необработанное исключение в 0x01323DB6 в файле SLlistSc.exe: 0xC0000005: место чтения нарушения доступа 0xFEEEFEF2». Это как-то связано с «этим» указателем, отображаемым в окне часов, поскольку у него есть нуль как в голове, так и в хвосте, я не знаю почему? –

+0

Я думаю, что вы делаете двойное удаление своих узлов. Деструктор узла удаляет узлы, а затем ваш деструктор списка удаляет узлы. – pstrjds

ответ

3

Вы пытаетесь использовать указатель, который является недопустимым, поскольку блок, содержащий этот указатель, был освобожден.

Библиотека времени выполнения отладки Microsoft C++ перезаписывает освобожденную память с помощью шаблона 0xFEEEFEEE, что облегчает определение этой проблемы.

+0

Что-нибудь с моим шаблоном? –

+0

Пожалуйста, задайте новый вопрос для вопросов шаблона, который не связан с проблемами указателя. –

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