我正在编写一个简单的程序,用于在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 :(得分:0)
您的程序中存在很多问题,在delete_element函数中,您的主要问题是您取消引用prevs
和nexts
而不检查它们是否为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。