Delete return memory problems - c++

I am writing a simple program for working with structure in C++. But there is a problem with memory. When my program calling a delete_element function it return memory's problem, but delete_all_list function working well. What I did wrong?
#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;
}

You have quite a few issues in your program, in the delete_element function your main problem is that you dereference prevs and nexts without checking whether they are NULL.
Adding some simple checks:
if (nexts && prevs)
prevs->next = nexts;
if (prevs && nexts)
nexts->prev = prevs;
Prevents it from segfaulting if any elements are NULL.
Other issues I have found I commented in the live example.

It looks suspicious that count starts from 1 instead 0 in delete_element. Because of this, the first index that your code is able to delete is 2 and you get into trouble if try to delete node 1.
EDIT: And one more thing: deleting the first node and last node needs some special care. For the first node, prev is 0 so you can not say prev->next.

Related

C++ How To Make a Dictionary With Binary Search Tree

I want to make a dictionary but I can not output 2 tree in my code
and I don't know what to do next:
WORD *t1 = NULL;
WORD *t2 = NULL;
WORD *t = NULL;
void InsertWordEN(WORD *t1, TD x)
{
if(t1 == NULL)
{
WORD *temp;
temp = new WORD;
strcpy(temp->data.EN, x.EN);
temp->left = NULL;
temp->right = NULL;
t1 = temp;
}
else
{
if (strcmp(t1->data.EN, x.EN) == 1)
{
InsertWordEN(t1->left,x);
}
else if(strcmp(t1->data.EN, x.EN) == 0)
{
InsertWordEN(t1->right,x);
}
}
}
void InsertWordVN(WORD *t2, TD x)
{
if(t2 == NULL)
{
WORD *temp;
temp = new WORD;
strcpy(temp->data.VN, x.VN);
temp->left = NULL;
temp->right = NULL;
t2 = temp;
}
else
{
if (strcmp(t2->data.VN, x.VN) == 1)
{
InsertWordVN(t2->left,x);
}
else if(strcmp(t2->data.VN, x.VN) == 0)
{
InsertWordVN(t2->right,x);
}
}
}
void InsertWord(TD &x)
{
cout<<"\EN: "; cin>>x.EN;
InsertWordEN(t1,x);
cout<<"\nVN: "; cin>>x.VN;
InsertWordEN(t2,x);
}
void OutputWord_NLR(WORD *t)
{
if(t1 != NULL)
{
cout<<t1->data.EN<<" ";
OutputWord_NLR(t1->left);
OutputWord_NLR(t1->right);
}
else if(t2 != NULL)
{
cout<<t2->data.VN<<" ";
OutputWord_NLR(t2->left);
OutputWord_NLR(t2->right);
}
}
int main()
{
int select; TD x;
InsertWord(x);
cout<<"\nOutput Tree EN and VN";
OutputWord_NLR(t);
getch();
return 0;
}
I think OutputWord_NLR function is wrong ?
BTS. It's too hard for me . I'm trying to understand it :)
Sorry ! It's seems too long . So I can't send at all my code

Pointer loses information when passing into function

edit, I'll try to give a better exemple:
first I'll tell your about the program:
basicly, there' two phases, the first is inserting the words (works perfectly fine)
struct trieLeaf {
keyType age = 1;
};
class Trie
{
private:
dataType character;
trieLeaf *leaf = nullptr;
class Trie **alphabet = nullptr;
int main()
{
string input;
Trie dictionary('\0');
while (getline(cin, input) && input[0] != '.')
{
dictionary.analyzeText(input);
}
while (getline(cin, input) && input[0] != '.')
{
dictionary.approxFind(input);
}
system("pause>null");
}
second phase is searching for words, if words is found then I need to reduce the number of times it has been added by 1.
if number of times it has been added is 0, then I remove it.
void Trie::approxFind(string &word)
{
int index = 0;
string result;
Trie *curr;
if (curr=find(word))
{
cout << curr->leaf->age << endl;
curr->leaf->age -= 1;
if (curr->leaf->age == 0)
{
remove(word);
}
}
else
{
result = approximate(word);
cout << "Did you mean " << result << "?\n";
}
}
Trie* Trie::find(const string &word)
{
int index = 0;
Trie *curr = this;
while (word[index] != '\0')
{
if (curr->alphabet[word[index] - 'a'] != nullptr)
{
curr = curr->alphabet[word[index++] - 'a'];
}
else
{
return (nullptr);
}
}
if (curr->leaf != nullptr)
{
return (curr);
}
}
void Trie::remove(const string &word)
{
int index = 0;
Trie *curr = this, **tempArr, *temp;
while (word[index] != '\0')
{
tempArr = curr->alphabet;
temp = curr;
curr = curr->alphabet[word[++index] - 'a'];
if (!isArrEmpty(tempArr))
{
delete(tempArr);
}
delete(temp);
temp = nullptr;
}
}
bool Trie::isArrEmpty(Trie **alphabet)
{
for (int index = 0; index < 26; index++)
{
if (!alphabet[index])
{
return (true);
}
}
return(false);
}
TempArr in isArrEmpty is losing the object it's pointing to when passing onto the funcion.
I hope it gives a better idea why

Quicksort Algorithm in a doubly linked list

I want to sort a list by last names with the algorithm of Quicksort but when exchanging the elements it does not work, it leaves them as they were
In this part the values of the chains are exchanged
void swap(string* a, string* b){
cout<<"A and B are "<<*a<<" - "<<*b<<endl;
string t = *a;
*a = *b;
cout<<" A is ->"<<*a<<endl;
*b= t;
cout<<"B is ->"<<*b<<endl;
}
This is where the partition is made. I have noticed that when * i and * j take values they are exactly the same names and therefore can not be compared later. It seems strange to me that this list works if it is a number but when it is strings this error occurs.
User *i = lower;
But this did not work at the end because the program crashed, but if you change the value of the string
User* partition(User *lower, User *high){
cout<<"Lower -> "<<lower->lastname<<endl;
cout<<"High -> "<<high->lastname<<endl;
string pivot = high->lastname;
User *i = bajo->prev;
for (User *j = lower; j != high; j = j->next)
{
if (j->lastname.compare(pivot)< 0)
{
i = (i == NULL)? lower : i->next;
cout<<"Atention J e I valen ->"<<i->lastname<<" - "<<j->lastname<<endl;
swap(&(i->lastname), &(j->lastname));
}
}
i = (i == NULL)? lower : i->lastname; // Similar to i++
swap(&(i->lastname), &(alto->lastname));
return i;
}
What am I failing? How can I make it really take the desired value.
EDITED:
This is the source code
#include <iostream>
#include<iomanip>
#include <string>
#include<cstdlib>
using namespace std;
class User
{
public :
string lastname;
User *next;
User *prev;
User()
{
lastname= "";
next=NULL;
prev=NULL;
}
int empty(User *listt)
{
if(listt == NULL)
{
return 1;
}
else
{
return 0;
}
}
User *Insert(User *listt, string lastName)
{
User *temp = new User();
if(empty(listt))
{
temp->lastname=lastName;
listt = temp;
}
else
{
temp->lastname=lastName;
listt->prev=temp;
temp->next=listt;
listt=temp;
}
return listt;
}
void swap(string* a, string* b)
{
string t = *a;
*a = *b;
*b= t;
}
User* partition(User* lower, User* high)
{
cout<<"Lower -> "<<lower->lastname<<endl;
cout<<"High -> "<<high->lastname<<endl;
string pivot = high->lastname;
User *i = lower->prev;
for (User *j = lower; j != high; j = j->next)
{
if (j->lastname.compare(pivot)< 0)
{
i = (i == NULL)? lower : i->next;
swap(&(i->lastname), &(j->lastname));
}
}
i = (i == NULL)? lower : i->next; // Similar to i++
swap(&(i->lastname), &(high->lastname));
return i;
}
User *Last(User *listt)
{
User *temp = listt;
while(temp && temp ->next)
temp=temp->next;
return temp;
}
void _quickSort( User* lower, User* high)
{
if(high != NULL && lower != high&&lower!= high->next)
{
User *p = partition(lower,high);
_quickSort(lower,p->next); //I change this part
_quickSort(p->next,high);
}
}
void quickSort(User *listt)
{
User *h = Last(listt);
_quickSort(listt, h);
}
User *Display(User *listt)
{
if(empty(listt))
{
cout<<"List empty"<<endl;
}
else
{
User *temp = new User();
temp = listt;
while(temp!= NULL)
{
cout<<"The last name is -> "<<temp->lastname<<endl;
temp=temp->next;
}
}
return listt;
}
};
int main()
{
User *listt = NULL;
User y;
bool exit = false;
int opc;
string lastName;
while(!exit)
{
cout<<"1.-Insert an element"<<endl;
cout<<"2.-Sort element-(Quicksort)"<<endl;
cout<<"3.-Show elements"<<endl;
cout<<"4.-Exitt"<<endl;
cin>>opc;
switch(opc)
{
case 1:
cout<<"Inser your last name"<<endl;
cin>>lastName;
listt=y.Insert(listt,lastName);
system("pause");
system("cls");
break;
case 2:
cout<<"Sorting...."<<endl;
y.quickSort(listt);
system("pause");
system("cls");
break;
case 3:
cout<<"Display..."<<endl;
y.Display(listt);
system("pause");
system("cls");
break;
case 4:
exit = true;
break;
}
}
}
Actually your swap function seems working but string t = *a; usage is kind of weird because *a is considered as an int value so you should not assign it to a string although the compiler can handle it either way. On the other hand I guess what you mentioned is to copy the value of "a" into a temporary string and it should be done as string* t = a; and then you can do b = t; but instead of that passing by reference is a better practice such as
void swap(string &a, string &b){
string t = a;
a = b;
b= t;
}
and you may want to check your Quick-sort implementation, see the reference on this page
_quickSort(lower,p->next); //I change this part
This should be p->prev. The correct function:
void _quickSort(User* lower, User* high)
{
if(high != NULL && lower != high&&lower != high->next)
{
User *p = partition(lower, high);
_quickSort(lower, p->prev); //change it back!
_quickSort(p->next, high);
}
}
Additionally there is resource leak in Display. Don't allocate new items in display function:
User *Display(User *listt)
{
if(empty(listt))
{
cout<<"List empty"<<endl;
}
else
{
//User *temp = new User(); <== don't allocate new item here
User *temp = listt;
while(temp!= NULL)
{
cout<<"The last name is -> "<<temp->lastname<<endl;
temp=temp->next;
}
}
return listt;
}
Testing with a 1000 items:
class User
{
public:
class Node
{
public:
string lastname;
Node *next;
Node *prev;
Node()
{
prev = next = nullptr;
}
};
Node *head;
User()
{
head = nullptr;
}
void Insert(string val)
{
Node *temp = new Node;
temp->lastname = val;
if (head)
{
head->prev = temp;
temp->next = head;
}
head = temp;
}
void swap(string &a, string &b)
{
string t = a;
a = b;
b = t;
}
Node *Tail()
{
Node *temp = head;
while(temp && temp->next)
temp = temp->next;
return temp;
}
Node* partition(Node* left, Node* right)
{
string pivot = right->lastname;
Node *i = left->prev;
for(Node *j = left; j != right; j = j->next)
{
if(j->lastname < pivot)
{
i = (i == nullptr) ? left : i->next;
swap(i->lastname, j->lastname);
}
}
i = (i == nullptr) ? left : i->next; // Similar to i++
swap(i->lastname, right->lastname);
return i;
}
void quickSort(Node* left, Node* right)
{
if(!left || !right || left == right || left == right->next)
return;
Node *p = partition(left, right);
quickSort(left, p->prev);
quickSort(p->next, right);
}
void quickSort()
{
quickSort(head, Tail());
}
void Display()
{
string last;
for (Node *n = head; n; n = n->next)
{
if(n->lastname < last)
{
cout << "error ***\n";
break;
}
last = n->lastname;
cout << n->lastname << endl;
}
}
};
int main()
{
User list;
list.Insert("z");
list.Insert("c");
list.Insert("a");
list.Insert("g");
for(int i = 0; i < 1000; i++)
{
string str;
for (int j = 0; j < 3; j++)
str.push_back('a' + rand() % 26);
list.Insert(str);
}
list.quickSort();
list.Display();
return 0;
}

C++ Linked List node counting (need help)

I'm trying to create a program that gets string input from a text file, inserting the content into a list, word by word. I also have to calculate the numbers of the duplicates. My program works fine for the small input text file (1 line of string). But whenever I feed it with a bigger text file, it crashes. Any help will be great.
Here is my code:
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
class Bag
{
private:
struct BagNode
{
string dataValue;
int dataCount;
BagNode *next;
BagNode(string);
};
BagNode *root;
string removePunctuations(string);
string toLower(string);
void insertData(string);
public:
Bag();
void procesFile(string, string);
void removeData(string);
void traverse();
};
Bag::BagNode::BagNode(string _data)
{
dataValue.assign(_data);
dataCount=1;
next = NULL;
}
Bag::Bag()
{
root = NULL;
}
void Bag::procesFile(string ifile, string ofile)
{
ifstream infile;
infile.open(ifile.c_str());
if (!infile.good())
{
cout<<"Input file not opening."<<endl;
return;
}
string line;
while(getline(infile,line))
{
stringstream lineStream(line);
string token = "";
while(lineStream >> token)
{
insertData(removePunctuations(token));
}
}
infile.close();
traverse();
cout<< endl <<"File processed successfully." << endl;
}
string Bag::removePunctuations(string data)
{
int length = data.size();
for(int i = 0; i < length; i++)
{
if(ispunct(data[i]))
{
data.erase(i--, 1);
length = data.size();
}
}
return data;
}
string Bag::toLower(string data)
{
for(int i = 0; data[i]; i++){
data[i] = tolower(data[i]);
}
return data;
}
void Bag::insertData(string data)
{
BagNode *n = new BagNode(data);
if (root == NULL)
{
root = n;
return;
}
BagNode *temp = root;
BagNode *prev = NULL;
string tdata;
data.assign(toLower(data));
while(temp != NULL)
{
tdata.assign(temp->dataValue);
tdata.assign(toLower(tdata));
if (tdata.compare(data) == 0)
{
temp->dataCount++;
return;
}
else
{
if (data.compare(tdata) < 0)
{
if (temp == root)
{
n->next = temp;
root = n;
return;
}
else
{
n->next = temp;
prev->next = n;
return;
}
}
}
prev = temp;
temp = temp->next;
}
n->next = temp;
prev->next = n;
}
void Bag::removeData(string data)
{
BagNode *temp = root;
BagNode *prev = NULL;
if (root->dataValue.compare(data)==0)
{
if (root->dataCount > 1)
root->dataCount--;
else
{
delete root;
root = NULL;
}
cout<<"Data removed successfully."<<endl;
return;
}
while (temp != NULL)
{
if (temp->dataValue.compare(data)==0)
{
if (temp->dataCount > 1)
temp->dataCount--;
else
{
prev->next = temp->next;
delete temp;
temp = NULL;
}
cout<<"Data removed successfully."<<endl;
return;
}
prev = temp;
temp = temp->next;
}
cout<<"Data not found match."<<endl;
}
void Bag::traverse()
{
if (root == NULL)
{
cout<<"No data."<<endl;
return;
}
BagNode *temp = root;
while(temp != NULL)
{
if (temp->dataCount > 1)
cout << temp -> dataValue << "(" << temp->dataCount << ")" << endl;
else
cout << temp -> dataValue << endl;
temp = temp->next;
}
}
int main(int argc, char *argv[])
{
bool outputConsole = false;
string infile, outfile = "\0";
cout << "Welcome!" << endl;
int option = -1;
do{
if (argc==1 || option == 1)
{
cout << "Enter the input file: ";
cin >> infile;
cout << "Enter the output file: ";
cin >> outfile;
}
else
{
infile.assign(argv[1]);
if (argc == 3)
outfile.assign(argv[2]);
}
Bag b;
b.procesFile(infile,outfile);
//b.traverse();
cout<<endl<<"If you want to input another file press 1 or 2 to quit: ";
cin>>option;
}while (option != 2);
return 0;
}
If ordering of words is not an issue,you should really try and use a hash table instead of a linked list as hash table is suitable for keeping track of duplicates.This will lead to O(1) insert operation (in ideal situation)

Doubly linked list always contains only 1 record

I am writing a simple program for working with structures in C++, but there is a problem I can't solve.
My program receives few structures as an input. It is supposed to sort them by the key and print them. But with my code I have always only one structure in my 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) {
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* start_new_list(int number) {
Struct* NewList = 0;
NewList = add_struct_to_list(0);
Struct* NewStruct = NewList;
int counter = 1;
for (counter; counter < number; counter++) {
NewStruct = add_struct_to_list(NewStruct);
}
return NewList;
}
void delete_all_list(Struct* list_begin) {
Struct* to_delete = list_begin->next;
Struct* next = 0;
delete[] list_begin;
if (to_delete != 0) {
do {
next = to_delete->next;
delete[] to_delete;
} while (next != 0);
}
}
void sort_by_age(Struct* list_begin) {
Struct* node = 0;
Struct* node2 = 0;
int age;
for (node = list_begin; node; node = node->next) {
for (node2 = list_begin; node2; node2 = node2->next) {
if (node->age < node2->age) {
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 = input("Number of students: ");
Struct* NewList = start_new_list(number);
sort_by_age(NewList);
print_list(NewList);
delete_all_list(NewList);
return 0;
}
Input:
Number of students: 3
Name: as
Age: 1
Name: as
Age: 2
Name: as
Age: 3
Output:
Age: 1; Name: as
Also note that this is homework and I must use structs.
UPD: Thanks to all for help!
You are trying to iterate through your list by using node->next pointer:
for (Struct* node = list_begin; node; node = node->next) {
cout << "Age: " << node->age << "; Name: " << node->text << endl;
}
But the way you are adding new Structs into your list is wrong, because you always set next to 0:
Struct* add_struct_to_list(Struct* prev) {
...
NewStruct->prev = prev;
NewStruct->next = 0;
return NewStruct;
}
Even if you allocate 3 new Structs, all of them will have pointer to next equal to 0. Proper way of adding new Struct to your list could look like this:
Struct* start_new_list(int number) {
Struct* prevStruct = NULL;
Struct* newList = NULL; // pointer to the first struct
for (int counter = 0; counter < number; counter++) {
Struct* newStruct = add_struct_to_list(prevStruct);
if (prevStruct) // if there was previous struct:
prevStruct->next = newStruct; // make it point to new struct
if (counter == 0) // if it is first allocated struct:
newList = newStruct; // store its address
prevStruct = newStruct; // store last struct as "prev"
}
return newList;
}
Also note that when you allocate memory by calling new, you should free it by calling delete. You are using delete[], which should be used when you allocate with new[]. Cleaning up your list should look like this:
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;
}
Hope this helps :)
NewStruct->next is always 0. Is this what you expect?
Also, you probably want to sort the structs as a unit rather than changing people's ages!