删除返回内存问题

时间:2013-03-11 08:02:24

标签: c++ memory linked-list structure

我正在编写一个简单的程序,用于在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;
}

2 个答案:

答案 0 :(得分:0)

您的程序中存在很多问题,在delete_element函数中,您的主要问题是您取消引用prevsnexts而不检查它们是否为NULL。

添加一些简单的检查:

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

如果任何元素为NULL,则阻止它进行segfaulting。

我发现的其他问题我在live example中发表了评论。

答案 1 :(得分:0)

看起来很可疑,计数从delete_element中的1开始而不是0。因此,您的代码能够删除的第一个索引是2,如果尝试删除节点1,则会遇到麻烦。

编辑:还有一件事:删除第一个节点和最后一个节点需要特别小心。对于第一个节点,prev为0,因此您不能说prev-&gt; next。