Linked list of pointers C++ - c++

I have a list, but now I have to link it.
Here is my program ( I deleted code inside functions, to make my program more easy to read ).
#include <iostream>
using namespace std;
struct Student
{
char ime[16];
char priimek[16];
char vpisna[10];
char ocenaRV[10];
char ocenaDN[10];
char ocenaKV[10];
char ocenaVI[10];
Student *next;
};
void clean(Student* pointer,int x) // Delete random data
{
}
void dodajanje(int x,Student* s) // Add information about student
{
}
void brisi(Student* pointer,int x) // Delete information about student
{
}
int main()
{
int student,mesto, brisanje, ali = 0;
cout << "Number of students?." << endl;
cin >> student;
Student* s = new Student[student];
clean(s,student);
cout << endl;
cout << "Add student to i place in array." << endl;
cin >> mesto;
dodajanje( mesto, s );
for(int i=0;i<(student*2);i++)
{
cout << "add student = 1, delete student = 2, cout information = 3"<<endl;
cin>>ali;
if (ali == 1)
{
cout << endl;
cout << "Add student to i place in array." << endl;
cin >> mesto;
dodajanje( mesto, s );
}
else if (ali == 2)
{
cout << "delete student on i place ?" << endl;
cin >> brisanje;
brisi(s,brisanje);
}
else
{
break;
}
}
delete[] s;
return 0;
}
Can someone explain me how to link my list, because code in all tutorials I came across was similar to this:
Node* temp = Node();
But in my program my code is:
Student* s = new Student[student];
And now I'm lost;
Note: I have to create dynamically linked list.

Node* temp = Node();
This creates a single Node instance. Though it should be this instead:
Node* temp = new Node;
Student* s = new Student[student];
This creates an array of student number of Student instances. This defeats the purpose of a linked list , as you won't be able to add/remove Student instances from the array efficiently. But, just for the sake of argument, lets say you really need an array. You can "link" the Student instances together like this:
for (int i = 0; i < (student-1); i++)
s[i].next = &s[i+1];
s[student-1].next = NULL;
If you actually need a linked list then you need something more like this instead:
Student *studentList = NULL;
Student *lastStudent = NULL;
for (int i = 0; i < student; ++i)
{
Student* s = new Student;
s->next = NULL;
if (lastStudent) lastStudent->next = s;
if (!studentList) studentList = s;
lastStudent = s;
}
// use studentList as needed...
Student *s = studentList;
while (s)
{
Student *next = s->next;
delete s;
s = next;
}
After fixing that, consider using the STL std::list class instead, or even std::forward_list in C++11.
That being said, you also need to rethink your code design. A linked list grows and shrinks dynamically, so there is no point in asking the user for the number of students up front, or pre-allocating the list with garbage that has to be cleaned before it can be used. Change your loop to run forever (or at least until the user says to stop). On each iteration, ask the user what to do. If Add, add a new Student to the list at that time. If Delete, ask the user which student to delete, find that Student, unlink it, and delete it. If Display, ask the user which student to display, find that Student, and display it. And so on.

Linked list is a node based data structure. What you are trying to do is creating a dynamic array of students not a linked list.
If you really need to create a linked list, in place of following line
Student* s = new Student[student];
you should create a nodes as follows in number of time of students in a for loop and link each other by updating student()-> next= next_student (Psuedo code)
Student* s = new Student;
And at end, you have to call delete s within a for loop to deallocate the memory.

Related

Store the address of an object inside a node

I'm trying to create an object of a class called Cell and store it in a linked list. I'm sure I could do this with an array, but part of my assignment is that I use a linked list and I didn't think I'd get this many problems. This is currently my node. Right now, I have all these variables stored in the node, but I'd rather create an object(Called "Cell") to store them. Info should be a pointer to an object of type T. Right now, that T should be of type Cell.
template<class T>
struct Node {
T *info;
Node<T> *nodeP;
Node<T> *linkP;
int nodeNumber = 0;
bool purchased = false;
std::string color = " ";
int index = 0;
int max_num = 0;
std::string name = " ";
int price;
};
In here I am creating the node and adding it to a linked list. At the moment I'm just filling in values of the node, but I'm trying to create an object of type Cell and assign it's address to the pointer info. I've tried a couple different ways but keep coming back with errors. I commented them out so you can see what I've tried.
template<class T>
void Board<T>::setCellValue() {
//open file
ifstream inFile;
string line;
inFile.open("CellValues.txt");
//Check for Error
if (inFile.fail()) {
cerr << "File does not exist!";
exit(1);
}
int index = 0, max_num = 0, count = 0, price = 0;
string color, name;
istringstream inStream;
while (getline(inFile, line)) {
inStream.clear();
inStream.str(line);
inStream >> color >> index >> max_num >> name >> price;
//creates node
Node<T> *newNodeP = new Node<T>;
//create pointer, assign pointer to pointer in Node
//Cell<T> *cellPtr = new Cell<T>(count, name, color, index, max_num, price);
//newNode->info= cellPtr;
//creating anonymous object and assigning to the node? I think
newNodeP->info = new Cell<T>(color, index, max_num, name, price);
//weird way I was just experimenting with
newNodeP->info->Cell<T>(count, name, color, index, max_num, price);
//fills node values(this is what I want to handle in the object
newNodeP->color = color;
newNodeP->index = index;
newNodeP->max_num = max_num;
newNodeP->name = name;
newNodeP->nodeNumber += count;
newNodeP->price = price;
newNodeP->linkP = NULL;
if (firstP != NULL)
lastP->linkP = newNodeP;
else
firstP = newNodeP;
lastP = newNodeP;
count++;
}
}
Currently, I have two ways of returning the node landed on. One returns a Node* and sort of works. It returns the pointer to the node, and I can access the values inside that node, but I can't figure out how to store the pointer to that node.
//Find Cell
template<class T>
Node<T>* Board<T>::findCell(int id) {
for (Node<T> *traverseP = firstP; traverseP != NULL; traverseP = traverseP->linkP) {
if (traverseP->nodeNumber == id) {
return traverseP;
}
}
return nullptr;
}
//how I call it in main. it returns an address to that node, but I'm getting errors trying to store that address in a pointer.
cout << "You landed on cell " << gameBoard.findCell(player.getCellNum()) << endl << endl;
Node<T> *ptr = gameboard.findCell(player.getCellNum())->info;
This second way, I think returns the reference to the object in the node, but my earlier problem is stopping me from figuring that out.
//Return Cell
template <class T>
T Board<T>::returnCell(int id) {
for (Node<T> *traverseP = firstP; traverseP != NULL; traverseP = traverseP->linkP) {
if (traverseP->nodeNumber == id) {
return traverseP->info;
}
}
return nullptr;
}
//How i'm calling it in main. I don't really know what it's returning though because it only prints "You landed on " and then nothing else.
cout << "You landed on " << gameBoard.returnCell(player.getCellNum()) << endl;

c++ pointer being freed was not allocated error

I am practcing c++'s new/delete, hashfunction and linked.
I made a practice by myself.
I have a struct which is
typedef struct student
{
int id;
string fName;
string lName;
student * nextStudent;
}Student;
Then in main function, I define an array of student
Student * table = new Student [10];
I have my own hash function which takes the id, and change to 0-9.
I want to add a student I do following
void addStudent(int studentId, string firstName, string lastName, Student *table)
{
// using hash function, convert the id into hashed id
int hashedID = hashFunction( studentId );
Student * pointer = &table[hashedID];
while(pointer->nextStudent !=NULL){
pointer = pointer->nextStudent;
}
// once we reach to the student who has NULL in nextStudent
// add student
Student *tmp = new Student;
tmp->id = studentId;
tmp->fName = firstName;
tmp->lName = lastName;
tmp->nextStudent = NULL;
// link
pointer->nextStudent = tmp;
}
I tested it, it seems fine.
The problem is deletion.
Since student variables are stored in dynamic memeory,
I need to use delete.
The following is my code.
void deleteAll(Student *table, int len)
{
for (int i = 0; i < len; i++)
{
Student* tmp = &table[i];
// delete student info except the last one
while ( tmp -> nextStudent !=NULL){
Student* tmp2;
tmp2 = tmp;
tmp = tmp->nextStudent;
delete tmp2;
}
}
}
I visited every student varialbes ane do the deletion.
I cannot find any probelm in my deletion funtion...
This is what I got after run..
malloc: *** error for object 0x7f85f1404b18: pointer being freed was not allocated
I have no clue what I have done wrong..
Can you help me?
EDIT...
As you guys metion
I added "delete [] table" in the main funtion..
Also, I remove "delete tmp" in deleteAll function; i think "delete [] table" will handle that part.
Still does not work..
By the way I forgot to added initTable function in the initial post.
initTable initialize the table...
void initTable (Student *table, int len)
{
for (int i = 0; i < len; ++i)
{
table[i].nextStudent = NULL;
}
}
Thank you.
The nextStudent field is never initialized, so all 10 elements created here have it pointing to unknown values.
Student * table = new Student [10];
This causes addStudent to loop until some pointer->nextStudent hits a NULL value by chance, then overwrite memory it doesn't own (unless it hits the lucky NULL on the first iteration).
while(pointer->nextStudent !=NULL) { ... }
The 'student` struct (btw, why the typedef?) should have a constructor to at least do this.
student::student() : nextStudent(NULL) { }
[ EDIT ] The other issue that #JonathanPotter duly pointed in a comment is that the head of each of the 10 student lists is a member of the table array. It is not dynamically allocated, and should not be individually deleted.
The qucik/easy fix would be to add a student destructor to recursively delete child nodes:
student::~student() { if(nextStudent) delete nextStudent; }
Then deleteAll would reduce to:
void deleteAll(student *table, int len)
{
for (int i = 0; i < len; i++)
{
student *tmp = &table[i];
if(tmp->nextStudent) delete tmp->nextStudent;
}
// this leaves the dynamically allocated table[] in place
// to delete it as well, just `delete [] table;`
}
However, such recursion may become impracticable once the lists grow large, and should better be rewritten as an iteration (without the recursive destructor).
student::~student() { }
// ...
void deleteAll(student *table, int len)
{
for(int i = 0; i < len; i++)
{
student *tmp = &table[i];
// delete student info except the *first* one
for(student *tmp2; tmp2 = tmp->nextStudent; )
{
tmp->nextStudent = tmp2->nextStudent;
delete tmp2;
}
}
// this leaves the dynamically allocated table[] in place
// to delete it as well, just `delete [] table;`
}
Then in main function, I define an array of student
Student * table = new Student [10];
First of all you are creating array of Student not Student*. And late you are trying to delete not allocated values. This is the reason of your program behavior.
To create pointer of array of pointers Student* you need the following:
Student** table = new Student*[10];
Than change your functions arguments from Student* table to Student** table and continue research.
Also do not forget to delete table using delete[] table;
Good Luck.

How to clear memory allocated for an array that's pointed to by a pointer correctly in C++?

Before you read my code, I want everyone to know that I am not using my code anywhere which is why it doesn't have much comments. It's just an example I wrote up to ask this question and it works the way I want it to. Feel free to try it out.
I have a question about my delete function. Does delete[] pTemp->top3Grades; actually delete/free all the array items? Does it know to stop after 3 elements? How? What if some data is right next to in memory which could be the same data (or same type of data) as the first 3? Is 3 passed secretly into the delete function so it knows when to stop? Or does it just delete pTemp->top3Grades[0], the first element?
And if possible, how would I check if it was deleted? I use XCode which come with a debugger if it helps.
#include <iostream>
using namespace std;
struct Students{
int idNum;
int age;
Students* pNext;
int* top3Grades;
};
void deleteAllStudents(Students* *head){
Students* pTemp = *head;
while (pTemp!=NULL) {
*head = pTemp->pNext;
delete[] pTemp->top3Grades; //Does this eliminate all 3 elments
//or just the first? How would you
//check if it is?
delete (pTemp); //Might as well ask...how I can see
//this was deleted/freed up?
pTemp=*head;
}
}
void addStudent(Students* *head, int id, int age, int grade1, int grade2, int grade3){
Students* studentEntry= new Students;
studentEntry->top3Grades= new int[3]; // Yes I could have set this as static when
// defining it in struct up above, but
// this way is related to my question later
studentEntry->top3Grades[0] = grade1;
studentEntry->top3Grades[1] = grade2;
studentEntry->top3Grades[2] = grade3;
studentEntry-> idNum = id;
studentEntry-> age = age;
studentEntry->pNext=NULL;
Students* pTemp;
pTemp = *head;
if (*head==NULL) {
*head = studentEntry;
} else{
while (pTemp->pNext!=NULL) {
pTemp= pTemp->pNext;
}
pTemp-> pNext= studentEntry;
}
}
void dispalyAllStudents(Students* *head){
Students* pTemp;
pTemp = *head;
while (pTemp!=NULL) {
cout<<"ID #: "<<pTemp->idNum<<" Age: "<<pTemp->age<<endl;
cout<<"Best grades are "
<<pTemp->top3Grades[0]<<" "
<<pTemp->top3Grades[1]<<" "
<<pTemp->top3Grades[2]
<<endl<<endl;
pTemp= pTemp->pNext;
}
}
int main()
{
int inputNum, studentID, studentAge, bestGrade1, bestGrade2, bestGrade3;
Students* pHead=NULL;
cout<< "How many records do you want to input? ";
cin >> inputNum;
for (int i = 0; i<inputNum; i++) {
cout<<endl;
cout<<"Enter ID Number: ";
cin>>studentID;
cout<<"Enter age: ";
cin>>studentAge;
cout<<"Enter first best grade: ";
cin>>bestGrade1;
cout<<"Enter second best grade: ";
cin>>bestGrade2;
cout<<"Enter third best grade: ";
cin>>bestGrade3;
addStudent(&pHead, studentID, studentAge, bestGrade1, bestGrade2, bestGrade3);
}
cout<< "--------"<<endl;
dispalyAllStudents(&pHead);
deleteAllStudents(&pHead);
return 0;
}
Yes, delete[] knows how many elements there are if you pass it a pointer that was returned from a call of new[]. In your code, you have essentially:
int * p = new int[3];
// ...
delete [] p;
That's exactly what it is designed to do.
How does it do that? That's not really your business. As for the present example, in the quasi-standard Itanium ABI for C++, there is nothing to do, and you essentially end up with a call of free() on the underlying memory. (So just use your existing understanding of free() to fill in the blanks.) If the type of the array element was not trivially destructible, the compiler would need to store the number of array elements somewhere in some "hidden" place (which the Itanium ABI specifies) so that it can call all the destructors.

c++ dynamic classes without using vector

So I happened to finish my homework program but today during lecture my good ol professor told us we are not allowed to use STL as in vectors or list to create our database. We were also told we need all our variables private. I was doing this program completely wrong. This is what I have so far.
in class.h
class Student {
private:
string last;
string first;
int student_id;
int enroll_id;
int *grades;
}
class Gradebook {
public:
Gradebook();
void newCourse(Gradebook *info);
private:
string name;
int course_id;
int count_course;
int enroll;
Student *students;
public:
//Constructor
}
I know I can access private members of Gradebook by using a constructor so I can set every member in my Gradebook.
function to create a newCourse
Gradebook::Gradebook() {
students = new Student;
course_id=0;
count_course=0;
enroll = 0;
}
Gradebook::newCourse(Gradebook *info) {
int i, loop=0;
cout << "Enter Number of Courses: ";
cin >> loop;
info = new Gradebook[loop];
for(i=0; i<loop; i++) {
cout << "Enter Course ID: ";
cin >> info[info->count_course].course_id;
cout << "Enter Course Name: ";
cin >> info[info->count_course].name;
info->count_course++
}
}
So Courses are now sets. Since the variables in Student are private. I can't just use a pointer to the variables to access them. Can someone show me how to do this?
Ok I didnt know how to ask this question but I actually answered it. But I want everyones opinion on my method.
class Student {
public:
void setID(int ID){student_id = ID; };
int getID(){return student_id);
private:
string last;
string first;
int student_id;
int enroll_id;
int *grades;
};
class Gradebook {
public:
Gradebook();
void newCourse(Gradebook *info);
void newStudent(Gradebook *info);
private:
string name;
int course_id;
int count_course;
int count_student;
int enroll;
Student *students;
public:
//Constructor
}
void Gradebook::newStudent() {
int i, loop=0;
int student=0;
string lastName;
cout << "Enter number of students: ";
cin >> loop;
for(i=0; i<loop; i++) {
cout << "Enter Student ID: ";
cin >> student;
info->students[info->count_student].setID(student);
cout << "Enter Last Name: ";
cin >> lastName;
info->students[info->count_student].setLast(lastName);
info->count_student++;
}
}
Is there anything wrong of doing it this way?
edit: You can't use 'Student *students' for your container for multiple Students...
You could use your own lists. Something like
struct Participant{ // or class (and maybe more clever name)
Student *student;
Participant *prev;
Participant *next;
};
You have to do little pointer-acrobatics, but maybe that's the idea for this exercise..
And like in previous answer, use get and set functions in your Student class.
Ok, I'm sorry but your code is a mess...
I can't do this homework for you, but here is few tips that came in mind
Are you sure that it wouldn't be easier to make different classes for Student, Course and Gradebook? I don't know your homework specifications, so I can't be sure what it is that your program should actually do.
You can not use int *grades to store all of one students grades. Same goes for Student *students. You can not access iterate *students like an array students[i].something()
If you use some help class(or struct) like Participant, you have to find right student by iterating in loop. Notice, that you have store 'first' participant inside your class and 'int students' keep in your student count (also inside your class)
Participant *current = first;
int id = Id; // Id is from function/method call
for(unsigned int i = 0; i < students; ++i){
if(current->getId()== id){
// do something and
break;
}
else if(current->next != NULL){ // test this just in case
current = current->next;
}
else break; // something went wrong
}
It might be good idea to store all students in one list (that you make) and use pointers in Course or in Gradebook or where ever... If you know 'static' here is a hint
class Student{
public:
. // get and set functions
static Student* getStudent(int id); // return NULL if no student with id
private:
static Student *first;
static Student *last;
static unsigned int counter; // helps with loops, but you can always use next != NULL
Student *next;
Student *prev;
}
Put this inside the Student constructor
with first student that you create you set first and last to point him/her, and next and prev to NULL. After that, always when you create a new student you set
this->prev = last;
last->next = this;
last = this;
this->next = NULL;
Do not implement program logic inside class. Do it in main() or in some other function, but i think main() is fine for now. If you need to add new student in gradebook, ask all the necessary info in main() and make some function like Gradebook::newStudent(int &Id, string &last_name){ // store student info in gradebook }
Usually these homework programming exercises don't have be too fancy or streamlined or fully optimized. So don't overdo them ;)
class Student {
private:
string last;
string first;
int student_id;
int enroll_id;
int *grades;
public:
string &getLast(){ return Last; }
...
...
};
Call Student::getLast() when you need to access your last variable etc
or
void setLast(string sLast){last = sLast;} for writing and
string getLast(){return last;} for reading
And example of dynamic array:
struct Student;
int Count = 0;
Student *Students = nullptr;
int AddStudent(Student nStudent)
{
Student *Buffer = new Student[Count + 1];
for (int a = 0; a < Count; a++)
Buffer[a] = Student[a];
Buffer[Count] = nStudent;
if(Students)
delete[] Students;
Students = Buffer;
return ++Count -1
}
void RemoveStudent(int Index)
{
Student *Buffer = new Student[Count - 1];
for (int a = 0; a < Index; a++)
Buffer[a] = Students[a];
for (int a = Index; Index < Count - 1; a++)
Buffer[a] = Students[a - 1];
if (Students)
delete[] Students;
Students = Buffer;
}

Double linked list implementation

I am having some syntax problems with a double linked list program I am writing for educational purposes. I have created a struct in my header file, and my main program seems to be alright, but implementing my functions in the .cpp file is giving me immense difficulty. I am having trouble discerning the three cases for inserting a record into the list. Specifically, allocating the memory, initializing the list head and tail, and the order of statements is confusing to me, as is passing a copy of the record to be added to my list.
My header file is as follows:
struct rec
{
char * id;
char firstname[15];
char lastname[15];
struct rec* prev;
struct rec* next;
};
int AddItem ( rec r );
int DeleteItem ( char* delid );
void PrintList ( int order );
My .cpp file, which is where the difficulty lies, is as follows:
#include <iostream>
#include "list.h"
#include <string.h>
using namespace std;
// These pointers refer to the head and tail of the list.
rec* first = NULL;
rec* last = NULL;
int AddItem( Rec r )
{
rec* newRecEntry;
rec* current = NULL;
rec* previous = NULL;
// Check for duplicate id
current = first;
while (current)
{
if( strcmp(current -> id, r.id) == 0)
{
return 0;
}
else
// Create a new node
{
newRecEntry = new Rec;
newRecEntry->id = new char[strlen(r.id)+1];
strcpy(newRecEntry->id, r.id);
strcpy(newRecEntry->firstname,r.firstname);
strcpy(newRecEntry->lastname,r.lastname);
newRecEntry->next = NULL;
newRecEntry->prev = NULL;
}
// Find the appropriate position for the node and insert accordingly
// Check to see if the list is empty
if (first == NULL)
{
first = newRecEntry;
last = newRecEntry;
}
else if ( r.lastname>last.lastname)
{
else
{
return 0;
}
/*int DeleteItem(char* ID)
I am supposed to be able to insert at the beginning, middle, and end of the list. Delete an item from the list based on the ID, and print the list in ascending or descending order based on user input, but I'd first simply like to handle the addition of items to said list.
My function definitions are as follows and also contains some errors
lists.cpp
#include <iostream>
#include "list.h"
#include <string.h>
using namespace std;
// These pointers refer to the head and tail of the list.
rec* first = NULL;
rec* last = NULL;
int AddItem( Rec r )
{
rec* newRecEntry;
rec* current = NULL;
rec* previous = NULL;
// Check for duplicate id
current = first;
while (current)
{
if( strcmp(current -> id, r.id) == 0)
{
return 0;
}
else
// Create a new node
{
newRecEntry = new Rec;
newRecEntry->id = new char[strlen(r.id)+1];
strcpy(newRecEntry->id, r.id);
strcpy(newRecEntry->firstname,r.firstname);
strcpy(newRecEntry->lastname,r.lastname);
newRecEntry->next = NULL;
newRecEntry->prev = NULL;
}
// Find the appropriate position for the node and insert accordingly
// Check to see if the list is empty
if (first == NULL)
{
first = newRecEntry;
last = newRecEntry;
}
else if ( r.lastname>last.lastname)
{
else
{
return 0;
}
/*int DeleteItem(char* ID)
{
rec
}
*/
/*void printList(int order)
{
loop
{
cout << ptr -> Id << " ";
cout << ptr -> firstname << " ";
cout << ptr -> lastname << " ";
cout << ptr -> prev << " "; // address of previous
cout << ptr << " "; // address of item
cout << ptr -> next << " "; // address of next item
}
}
Main is as follows:
#include <iostream>
#include "list.h"
#include <string.h> // <string>
using namespace std;
void main (void)
{
int choice, printorder;
char idbuffer[100];
rec r;
do
{
cout << "Enter your choice 1 Add, 2 Delete, 3 Print, 0 quit "<<endl;
cin >> choice;
switch ( choice )
{
case 1: //AddItem
cout << "\nEnter ID ";
cin >> idbuffer;
r.id = idbuffer;
cout << "\nFirst Name ";
cin >> r.firstname;
cout << "\nLast Name ";
cin >> r.lastname;
if ( AddItem ( r ) )
{
cout << "\nSuccess!\n";
}
else
{
cout << "\nItem failed to be added\n";
}
break;
case 2: //Delete
cout << "\nEnter id :";
cin >> idbuffer;
if ( DeleteItem ( idbuffer ) )
{
cout << "\nDelete OK\n";
}
else
{
cout << "\nDelete Failed for " << idbuffer;
}
break;
case 3: // Print
cout << "Enter order 0 - Ascending, 1 - Descending\n";
cin >> printorder;
PrintList (printorder);
break;
case 0: // quit
break;
default: // bad choice
break;
} // end switch
}
while ( choice != 0 );// end do while
} // end main
It may not seem like it, but even this function
int AddItem(Record entry)
{
Record* newRecordPointer;
newRecordPointer=new Record;
strcpy(newRecordPointer->firstName,entry.firstName);
strcpy(newRecordPointer->lastName,entry.lastName);
newRecordPointer->ID=new char[strlen(entry.ID)+1];
strcpy(newRecordPointer->ID, entry.ID);
return 0;
}
is trying to do too many things.
Let's write the pseudocode description of adding an item to a list:
create a new node
populate the new node with the values provided
attach the new node to the list
I've marked the verbs and nouns involved, and you can already see one of the nouns is missing from your function. You're asking AddItem to add an item to a list ... but you don't give it a list to work on.
It's also useful to write out your expectations clearly:
before AddItem is called:
it needs a list to work on
we don't have a list container class, just the records, so we have to pass a Record
let's say we want to add our new item after the Record passed in
after AddItem is called:
whatever Record we passed in, its Next should point to the new node
the new node's Previous should point to the node passed in
etc. etc. (these are the standard doubly-linked list insertion behaviours)
note for later: we haven't described how we store an empty list
if it's a circular list, an empty list will be a Record whose Next and Previous members point to itself
if it's linear, they might both be NULL instead
it could just be a NULL pointer, but then adding the first node to an empty list needs more effort
So, let's say the minimal function that could possibly work is:
void AddItem(Record *insert_after, Record value)
{
Record *new_node = CreateRecord();
CopyRecordValues(new_node, &value);
AttachAfter(insert_after, new_node);
}
Note that if we were writing real C++ the first two lines could just use the copy constructor Record *new_node = new Record(value), but it will take more changes than that to reach idiomatic C++ code from where we started.
Now, given that, can you:
implement those three functions? (CreateRecord and CopyRecordValues are already handled in your current code)
write the equivalent pseudocode for your other operations, and translate it yourself?
Try changing this:
int AddItem(Record entry);
To this:
Record* AddItem(Record entry, Record *insertion_point = NULL );
If insertion_point is NULL, you can assume that the Record is the beginning of a new list.
Now you have enough information to set Next and Previous pointers, and return the newly created node.