2013-03-11 58 views
0

我正在寫一個簡單的程序來處理C++中的結構。但是內存有問題。當我的程序調用delete_element函數時,它會返回內存的問題,但delete_all_list函數運行良好。我做錯了什麼?刪除返回內存問題

#include "iostream" 
#include "string.h" 
#include "limits" //ignore max 
#include "stdlib.h" //atof 
using namespace std; 

struct Struct { 
    char text[10]; 
    int age; 
    Struct *prev; 
    Struct *next; 
}; 

int input(string msg) { 
    char str[2]; 
    int check = 0, len = 0, var = 0, i = 0; 
    while (1){ 
     cin.tellg(); 
     cout<<msg; 
     cin.getline(str, 2); 
     if (cin.fail()) { 
      cin.clear(); 
      cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
     } 
     len = strlen(str); 
     check = 0; 
     for (i=0;i<len;i++) { 
      if(isdigit(str[i])) { 
       check++;  
      }       
     } 
     if (check==len && !(check==1 && str[0]=='-') && check != 0 && atoi(str) != 0){ 
      var = atoi(str); 
      return var; 
     }  
     else { 
      cout<<"Error!"<<endl; 
     } 

    } 
} 

Struct* add_struct_to_list(Struct* prev){ 
    Struct *NewStruct = 0; 
    char str[10];  
    int age;   
    cout<<"Name: "; 
    cin.getline(str, 10); 
    if (cin.fail()){ 
     cin.clear(); 
     cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
    } 
    age = input("Age: "); 
    NewStruct = new Struct;  
    strcpy(NewStruct->text, str); 
    NewStruct->age = age; 
    NewStruct->prev= prev;  
    NewStruct->next= 0;  
    return NewStruct;  
} 

Struct* add_empty_struct_to_list(Struct* list_begin, int index){ 
    int count = 1; 
    Struct* node = list_begin; 
    while (node->next) { 
     node = node->next; 
     count++; 
    } 
    while (count != index) { 
     Struct* NewStruct = new Struct; 
     strcpy(NewStruct->text, " "); 
     NewStruct->age = 0; 

     NewStruct->prev = node; 
     node->next = NewStruct; 

     NewStruct->next = NULL; 
     node = NewStruct; 
     count++; 
    } 
    return node; 
} 

void insert_struct_to_list(Struct* prev, Struct* next){ 
    Struct *NewStruct = 0; 
    char str[10];  
    int age;   
    cout<<"Name: "; 
    cin.getline(str, 10); 
    if (cin.fail()){ 
     cin.clear(); 
     cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
    } 
    age = input("Age: "); 

    NewStruct = new Struct;  
    strcpy(NewStruct->text, str); 
    NewStruct->age = age; 

    NewStruct->prev= prev; 
    NewStruct->next= next; 

    prev->next = NewStruct; 
    next->prev = NewStruct; 
} 

void replace_struct_in_list(Struct* ReStruct){ 
    char str[10];  
    int age;   
    cout<<"Name: "; 
    cin.getline(str, 10); 
    if (cin.fail()){ 
     cin.clear(); 
     cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
    } 
    age = input("Age: ");  
    strcpy(ReStruct->text, str);  
    ReStruct->age = age; 
} 

Struct* start_new_list(int number) { 
    Struct* prevStruct = NULL; 
    Struct* newList = NULL;     
    for (int counter = 0; counter < number; counter++) { 
     Struct* newStruct = add_struct_to_list(prevStruct); 
     if (prevStruct)      
      prevStruct->next = newStruct; 
     if (counter == 0)     
      newList = newStruct;    
     prevStruct = newStruct;    
    } 
    return newList; 
} 

Struct* find_a_struct(Struct* list_begin, int index){ 
    Struct* node = list_begin->next; 
    int count = 1; 
    if (node != NULL) {   
     while (node->next) {  
      node = node->next; 
      count++; 
      if (count == index) { 
       break; 
      } 
     } 
     if (count < index) { 
      node = NULL; 
     } 
    } 
    return node; 
} 

void add_extra_struct_to_list(Struct* list_begin) { 
    string command; 
    Struct* NewStruct = NULL; 
    int index = input("Enter index of new element (it should be less then 99): "); 
    Struct* FindedStruct = find_a_struct(list_begin, index); 
    if (FindedStruct != NULL) {   
     while (true) { 
      cout<<"This index is already exist. Replace? (Yes/No): "; 
      cin>>command; 
      cout<<endl; 
      if (command == "Yes" || command == "No") { 
       break; 
      } 
     } 
     if (command == "No") { 
      insert_struct_to_list(FindedStruct->prev, FindedStruct); 
     } else { 
      replace_struct_in_list(FindedStruct); 
     } 
    } else { 
     NewStruct = add_empty_struct_to_list(list_begin, index); 
     Struct* ExtraStruct = add_struct_to_list(NewStruct->prev); 
     NewStruct->next = ExtraStruct; 
    } 
} 

void delete_element(Struct* node) { 
    int index = 0; int count = 1; 
    bool is_index = false; 
    do { 
     index = input("Enter number of index: "); 
    } while (index <= 0); 
    do { 
     node = node->next; 
     count++; 
     if (count == index) { 
      Struct* prevs = 0; 
      prevs = node->prev; 
      Struct* nexts = 0; 
      nexts = node->next; 
      delete node; 
      prevs->next = nexts; 
      nexts->prev = prevs; 
      is_index = true; 
      break; 
     } 
    } while (node->next); 
    if (is_index == true) { 
     cout<<"Done!"<<endl; 
    } else { 
     cout<<"Index is out off range!"<<endl; 
    } 
} 

void delete_all_list(Struct* list_begin) { 
    Struct* structToDelete = NULL; 
    Struct* node = list_begin; 
    while (node->next) { 
     structToDelete = node; 
     node = node->next; 
     delete structToDelete; 
    } 
    delete node; 
} 

void sort_by_age(Struct* list_begin) { 
    Struct* node = 0; 
    Struct* node2 = 0; 
    int age; char text[10]; 
    for (node = list_begin; node; node = node->next) { 
     for (node2 = list_begin; node2; node2 = node2->next) { 
       if (node->age < node2->age) { 
        strcpy(text, node->text); 
        strcpy(node->text, node2->text); 
        strcpy(node2->text, text); 
        age = node->age; 
        node->age = node2->age; 
        node2->age = age; 
      } 
     } 
    } 
} 

void print_list(Struct* list_begin) { 
    for (Struct* node = list_begin; node; node = node->next) { 
      cout<<"Age: "<<node->age<<"; Name: "<<node->text<<endl; 
    } 
} 

int main() { 
    int number; 
    Struct *NewList = 0; 
    string command; 
    bool list = false; 
    cout<<"\"help\" for more info"<<endl<<endl; 
    while (true) { 
     cout<<">>> "; 
     cin>>command; 
     cout<<endl; 
     if (command == "help") { 
      cout<<"startlist - creating a new double-linked list."<<endl; 
      cout<<"sortlist - sorting list by age of workers."<<endl; 
      cout<<"printlist - prining all list's elements."<<endl; 
      cout<<"addextra - adding extra element to list."<<endl; 
      cout<<"delete - delete element from list."<<endl; 
      cout<<"deletelist - delet all list. (Warning: require for create new list!)"<<endl; 
      cout<<"exit - close program."<<endl; 
     } else if (command == "startlist") { 
      if (list == false) { 
       number = input("Number of worker (it should be less than 99): "); 
       NewList = start_new_list(number); 
       cout<<"Done!"<<endl; 
       list = true; 
      } else { 
       cout<<"Error: You allready create one!"<<endl; 
      } 
     } else if (command == "sortlist"){ 
      if (list == true) { 
       sort_by_age(NewList); 
       cout<<"Done!"<<endl; 
      } else { 
       cout<<"Error: You did't create a list or it is already sorted!"<<endl; 
      } 
     } else if (command == "printlist") { 
      if (list == true) { 
       print_list(NewList); 
      } else { 
       cout<<"Error: You did't create a list!"<<endl; 
      } 
     } else if (command == "delete") { 
      if (list == true) { 
       delete_element(NewList); 
      } else { 
       cout<<"Error: You did't create a list!"<<endl; 
      } 
     } else if (command == "deletelist") { 
      if (list == true) { 
       delete_all_list(NewList); 
       cout<<"Done!"<<endl; 
       list = false; 
      } else { 
       cout<<"Error: You did't create a list!"<<endl; 
      } 
     } else if (command == "addextra") { 
      if (list == true) { 
       add_extra_struct_to_list(NewList); 
      } else { 
       cout<<"Error: You did't create a list!"<<endl; 
      } 
     } else if (command == "exit") { 
      if (list == true) { 
       delete_all_list(NewList); 
       cout<<"Done!"<<endl; 
      } 
      break; 
     } else { 
      cout<<"Error: There is no such command!"<<endl; 
     } 
     cout<<endl; 
    } 
    return 0; 
} 
+0

您應該使用顯示問題的這些函數發佈代碼。 – Philipp 2013-03-11 08:15:56

回答

0

您在程序中有相當多的問題,在delete_element功能的主要問題是,取消引用prevsnexts不檢查其是否爲空。

添加一些簡單的檢查:

if (nexts && prevs) 
    prevs->next = nexts; 
if (prevs && nexts) 
    nexts->prev = prevs; 

從如有元件是NULL防止段錯誤它。

我發現的其他問題我評論了live example

+0

使用add_struct_to_list函數使用new添加的元素。 delete_all_list工作正常。 – 2013-03-11 08:14:38

+0

儘管這看起來像不好的風格,但如果他傳遞一個以前的'new'ed指針並不會在其他任何地方刪除它,這不一定是錯誤的。 – Philipp 2013-03-11 08:15:32

+0

我該如何解決這個問題?有其他方法嗎? – 2013-03-11 08:18:17

0

看起來可疑的是count從delete_element中的1開始,而不是0。因此,您的代碼能夠刪除的第一個索引是2,如果嘗試刪除節點1,則會遇到問題。

編輯:另外還有一件事:刪除第一個節點和最後一個節點需要特別注意。對於第一個節點,prev是0,所以你不能說prev-> next。

+0

是的,但這不是問題。因爲索引它計數索引從1 – 2013-03-11 08:26:00

+0

謝謝,我會重寫第一個和最後一個元素的代碼。 – 2013-03-11 08:31:38