c++ linked list inside another one - c++

I'm trying to make a linked list inside another one, here is my code
template<typename T>
class List {
private:
int length;
class Node {
public:
T data;
Node* next;
} *head;
public:
List();
~List();
void insert(T item);
void remove(T item);
void empty();
T* getAll();
int count() const;
};
template<typename T>
void List<T>::insert(T item)
{
if (head == NULL)
{
head = new Node();
head->data = item;
head->next = NULL;
length = 1;
return;
}
Node* p = new Node();
p->data = item;
p->next = head;
head = p;
++length;
}
struct Remainder {
Date dt;
List<int> notes;
};
void getDayEvents(Date dt, List<Remainder> l)
{
Remainder* arr = new Remainder[l.count()];
arr = l.getAll();
for (int i = 0; i < l.count(); i++)
{
if (arr[i].dt.day == dt.day && arr[i].dt.month == dt.month && arr[i].dt.year == dt.year)
{
int* nArr = new int[arr[i].notes.count()];
nArr = arr[i].notes.getAll();
for (int j = 0; j < arr[i].notes.count(); j++)
{
cout << nArr[j] << endl;
}
}
}
}
int _tmain() {
Date dt1, dt2;
dt1.setDate(17, 7, 2015);
dt2.setDate(5, 11, 2015);
Remainder r1, r2;
r1.dt = dt1;
r1.notes.insert(1);
r1.notes.insert(2);
r2.dt = dt2;
r2.notes.insert(5);
List<Remainder> l;
l.insert(r1);
l.insert(r2);
getDayEvents(dt1, l);
//----------------------------------------------------------
int pause;
cin >> pause;
return 0;
}
just when insert r1 or r2 in the list, the data inside lists of notes inside each remainder just disappeared or destroyed
I don't know why? Where is the mistake?

You're passing your objects into the insert function by value.
That means copy constructors and destructors are being called.
You did not declare the copy constructor of List so it's presumably
being generated by the compiler, and presumably is making a
"shallow" copy of the List when the copy constructor
of Remainder makes copies of the members of the input Remainder.
I think this copies the pointer head from one List to another
so that now you have
two List objects whose head pointers point to the same object.
You haven't shown the definition of the List destructor,
but depending on what you do in that destructor it could be deleting
a Node that the destroyed List points to while another List
still has a pointer to the same Node.
That may sound confusing, and frankly I'm not sure I can count the
invocations of constructors and destructors correctly myself,
so best to just make sure they can never be used unsafely.
A good start might be to define your own copy constructor and
operator = for List in such a way that the new List has
newly-allocated copies of everything that was in the old List.
Never let two head pointers point to the same object.
After you've inserted one List into another, you should be able to
confirm in the debugger that the new copy of the List

Related

array transfer constructor function c++

I am trying to learn constructors in c++. I am working on a list that I defined. I managed to get the copy constructor working, but I have problems with the array transfer constructor. Any help will be appreciated. Thanks!
The array transfer constructor supposedly should take in an array and a size(int) and output a list with that size.
ex: input: data = {1,3,5,6};int = 5;output = {1,3,5,6,0}
edit: change n to i
#include <iostream>
using namespace std;
class list_element{
public:
list_element(int n = 0,list_element* ptr = nullptr):
d(n),next(ptr){}
int d;
list_element* next;
};
class List{
public :
List():head(nullptr),cursor(nullptr){}
List(const int* arr, int n); // copy array transfer data
List(const List& lst); //copy constructor
void prepend(int n);
int get_element()
{
return cursor->d;
}
void advance() { cursor = cursor->next; }
void print();
~List(); //delete
private:
list_element* head;
list_element* cursor;
};
//transfer array
List::List(const int* arr, int n) {
List temp;
int i = 0;
while (i < n)
{
head = new list_element(arr[i], head);
++i;
}
}
//delete
List::~List(){
for (cursor = head; cursor != 0;)
{
cursor = head->next;
delete head;
head = cursor;
}
}
//deep copy constructor
List::List(const List& lst) {
if (lst.head == nullptr)
{
head = nullptr; cursor = nullptr;
}
else
{
cursor = lst.head;
list_element* h = new list_element();
list_element* previous;
head = h;
h->d = lst.head->d;
previous = h;
for (cursor = lst.head; cursor != 0;)
{
h = new list_element();
h->d = cursor->d;
previous->next = h;
cursor = cursor->next;
previous = h;
}
cursor = head;
}
}
void List::prepend(int n)
{
if (head == nullptr)
cursor = head = new list_element(n, head);
else
head = new list_element(n, head);
}
void List::print()
{
list_element* h = head;
while (h != 0)
{
cout << h->d << ',';
h = h->next;
}
cout << "###" << endl;
}
int main()
{
List a, b;
//change size
int data[10] = { 1,3,5,7};
List d(data, 10);
d.print();
return 0;
}
Main Question
With regards to your 'from_array' constructor, you have a temporary List variable that you are not using and is also unnecessary.
Second you are assigning the head pointer each time meaning that by the end of the constructor call, head now points to the last element you constructed.
Third your list_element constructor is taking the old head pointer which points to the previous element meaning the list is tries to advance from the bottom element upwards through the list, causing the reversed read you mentioned in a comment.
You can fix this two ways. First, you could reverse the order you read the input array so it constructs your linked-list back to front.
List::List(const int* arr, int n)
{
int i = n - 1;
list_element* it = new list_element(arr[i], nullptr); ///< Last element
--i;
while (i > -1)
{
it = new list_element(arr[i], it);
--i;
}
head = it; ///< assign head to the last instance of it.
it = nullptr;
}
However, there is a better why that expresses the linking of the elements more intuitively. First you need to pre-construct the next element and give it some default values (I didn't bother implementing a default constructor for list_element but you might want to.) and assign it to next, then assign head to a new list_element passing in the pointer to next. increment i so that you can assign next's value to the second value in the array. Finally incremenet i again so we can loop through the rest of the array. Finally, in the while loop, copy next into a variable called prev. Assign next to a new list_element with the value from the array and a nullptr. Finally assign prev->next to the new next pointer and increment i.
list_element::list_element()
List::List(const int* arr, int n)
{
int i = 0;
list_element* next = new list_element(0, nullptr);
head = new list_element(arr[i], next);
++i;
next->d = arr[i];
++i;
while (i < n)
{
list_element* prev = next;
next = new list_element(arr[i], nullptr);
prev->next = next;
++i;
}
}
Side Notes
Because you stated you are tying to learn about C++ constructors (and I'm assuming data structures) I would suggest starting with a static array type similar to std::array as it's constructors a bit more trivial to implement or even just start with simple classes/struct that just hold simple data like a few ints or whatnot as you can get an idea for the semantics around the various constructors in C++.
Also, the C++ standard library has two linked list types (std::list and std::foward_list)
Finally, you might be better off using a std::initializer_list instead of a raw array as this give you iterators to the data you want to copy which is a bit nicer to use.
Best of luck in your learning journey.
Try to avoid using variable names like 'n', which could be very confusing.
In your copy constructor for transferring the array, you should not access the array using 'n', which is the desired size of the transferred array, nor increment it.
Additionally, sizeof(arr) doesn't work as you would expect. You are querying the size of the pointer.

Linked List: How to implement Destructor, Copy Constructor, and Copy Assignment Operator? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 months ago.
Improve this question
This is my C++ code:
#include <iostream>
using namespace std;
typedef struct Node
{
int data;
Node* next;
}Node;
class LinkedList
{
private:
Node* first;
Node* last;
public:
LinkedList() {first = last = NULL;};
LinkedList(int A[], int num);
~LinkedList();
void Display();
void Merge(LinkedList& b);
};
// Create Linked List using Array
LinkedList::LinkedList(int A[], int n)
{
Node* t = new Node;
if (t == NULL)
{
cout << "Failed allocating memory!" << endl;
exit(1);
}
t->data = A[0];
t->next = NULL;
first = last = t;
for (int i = 1; i < n; i++)
{
t = new Node;
if (t == NULL)
{
cout << "Failed allocating memory!" << endl;
exit(1);
}
t->data = A[i];
t->next = NULL;
last->next = t;
last = t;
}
}
// Deleting all Node in Linked List
LinkedList::~LinkedList()
{
Node* p = first;
Node* tmp;
while (p != NULL)
{
tmp = p;
p = p->next;
delete tmp;
}
}
// Displaying Linked List
void LinkedList::Display()
{
Node* tmp;
for (tmp = first; tmp != NULL; tmp = tmp->next)
cout << tmp->data << " ";
cout << endl;
}
// Merge two linked list
void LinkedList::Merge(LinkedList& b)
{
// Store first pointer of Second Linked List
Node* second = b.first;
Node* third = NULL, *tmp = NULL;
// We find first Node outside loop, smaller number, so Third pointer will store the first Node
// Then, we can only use tmp pointer for repeating process inside While loop
if (first->data < second->data)
{
third = tmp = first;
first = first->next;
tmp->next = NULL;
}
else
{
third = tmp = second;
second = second->next;
tmp->next = NULL;
}
// Use while loop for repeating process until First or Second hit NULL
while (first != NULL && second != NULL)
{
// If first Node data is smaller than second Node data
if (first->data < second->data)
{
tmp->next = first;
tmp = first;
first = first->next;
tmp->next = NULL;
}
// If first Node data is greater than second Node data
else
{
tmp->next = second;
tmp = second;
second = second->next;
tmp->next = NULL;
}
}
// Handle remaining Node that hasn't pointed by Last after while loop
if (first != NULL)
tmp->next = first;
else
tmp->next = second;
// Change first to what Third pointing at, which is First Node
first = third;
// Change last pointer from old first linked list to new last Node, after Merge
Node* p = first;
while (p->next != NULL)
{
p = p->next;
}
last = p;
// Destroy second linked list because every Node it's now connect with first linked list
// This also prevent from Double free()
b.last = NULL;
b.first = NULL;
}
int main()
{
int arr1[] = {4, 8, 12, 14, 15, 20, 26, 28, 30};
int arr2[] = {2, 6, 10, 16, 18, 22, 24};
int size1 = sizeof(arr1) / sizeof(arr1[0]);
int size2 = sizeof(arr2) / sizeof(arr2[0]);
LinkedList l1(arr1, size1);
LinkedList l2(arr2, size2);
l1.Display();
l2.Display();
// Merge two linked list, pass l2 as reference
l1.Merge(l2);
l1.Display();
return 0;
}
I'm beginner on C++ and in this code, I practice how to Merge two linked list. This actually works perfectly. I've successfully Merge the two Linked List in sorted order.
But, there's people said that I should've follow the Rule of Three on C++. Which implement: Destructor, Copy Constructor, and Copy Assignment Operator.
I've watched many videos about that. I do understand that is basically handle Shallow Copy especially when we don't want two different object point to the same address of memory. But, for my problem is, I still don't know how to Implement it on a Class that working on a Linked List just like my code above.
Someone said, in my main(), this code: l1.Merge(l2); is somehow incorrect because I don't have explicit Copy Constructor.
And if you look at my Merge() function, in Last line, if I didn't to this: b.last = NULL; and b.first = NULL; , which simply destroy pointer of Second Linked list, the Compiler give me warning: Double free() detected.
So, I think my question is:
How can this code: l1.Merge(l2); is have something to do with Copy Constructor?
Is Double free() happened because I don't implement the Rule of Three? If yes, how to address them?
How to write the Rule of Three based on my code? When or How to use them?
Based on this Code, is there something wrong? Do I still need the Rule of Three if my Program only want to Merge Linked List?
Thank You. I hope someone can explain to me like I'm 10 years old. and hope someone can write me some Code.
But, for my problem is, I still don't know how to Implement [Rule of Three] on a Class that working on a Linked List just like my code above.
You simply implement the copy constructor and copy assignment operator to iterate the input list, making a copy of each node and inserting them into your target list. You already have a working destructor. In the case of the copy assignment operator, you can usually use the copy-swap idiom to implement it using the copy constructor to avoid repeating yourself.
Someone said, in my main(), this code: l1.Merge(l2); is somehow incorrect because I don't have explicit Copy Constructor.
Then you were told wrong. Your Merge() code has nothing to do with a copy constructor.
And if you look at my Merge() function, in Last line, if I didn't to this: b.last = NULL; and b.first = NULL;, which simply destroy pointer of Second Linked list, the Compiler give me warning: Double free() detected.
Correct. Since you are moving the nodes from the input list to the target list, you need to reset the input list so it doesn't point at the moved nodes anymore. Otherwise, the destructor of the input list will try to free them, as will the destructor of the target list.
How can this code: l1.Merge(l2); is have something to do with Copy Constructor?
It doesn't have anything to do with it.
Is Double free() happened because I don't implement the Rule of Three?
Not in your particular example, as you are not performing any copy operations. But, in general, not implementing the Rule of Three can lead to double frees, yes.
How to write the Rule of Three based on my code?
See the code below.
Do I still need the Rule of Three if my Program only want to Merge Linked List?
No. Only when you want to make copies of lists.
With that said, here is an implementation that includes the Rule of Three:
#include <iostream>
#include <utility>
struct Node
{
int data;
Node *next;
};
class LinkedList
{
private:
Node *first;
Node *last;
public:
LinkedList();
LinkedList(const LinkedList &src);
LinkedList(int A[], int num);
~LinkedList();
LinkedList& operator=(const LinkedList &rhs);
void Display() const;
void Merge(LinkedList &b);
};
// Create Linked List using default values
LinkedList::LinkedList()
: first(NULL), last(NULL)
{
}
// Create Linked List using Array
LinkedList::LinkedList(int A[], int n)
: first(NULL), last(NULL)
{
Node **p = &first;
for (int i = 0; i < n; ++i)
{
Node *t = new Node;
t->data = A[i];
t->next = NULL;
*p = t;
p = &(t->next);
last = t;
}
}
// Create Linked List by copying another Linked List
LinkedList::LinkedList(const LinkedList &src)
: first(NULL), last(NULL)
{
Node **p = &first;
for (Node *tmp = src.first; tmp; tmp = tmp->next)
{
Node* t = new Node;
t->data = tmp->data;
t->next = NULL;
*p = t;
p = &(t->next);
last = t;
}
}
// Deleting all Node in Linked List
LinkedList::~LinkedList()
{
Node *p = first;
while (p)
{
Node *tmp = p;
p = p->next;
delete tmp;
}
}
// Update Linked List by copying another Linked List
LinkedList& LinkedList::operator=(const LinkedList &rhs)
{
if (&rhs != this)
{
LinkedList tmp(rhs);
std::swap(tmp.first, first);
std::swap(tmp.last, last);
}
return *this;
}
// Displaying Linked List
void LinkedList::Display() const
{
for (Node *tmp = first; tmp; tmp = tmp->next)
std::cout << tmp->data << " ";
std::cout << std::endl;
}
// Merge two linked list
void LinkedList::Merge(LinkedList& b)
{
if ((&b == this) || (!b.first))
return;
if (!first)
{
first = b.first; b.first = NULL;
last = b.last; b.last = NULL;
return;
}
// Store first pointer of Second Linked List
Node *second = b.first;
Node *third, **tmp = &third;
// We find first Node outside loop, smaller number, so Third pointer will store the first Node
// Then, we can only use tmp pointer for repeating process inside While loop
// Use while loop for repeating process until First or Second hit NULL
do
{
// If first Node data is smaller than second Node data
if (first->data < second->data)
{
*tmp = first;
tmp = &(first->next);
first = first->next;
}
// If first Node data is greater than second Node data
else
{
*tmp = second;
tmp = &(second->next);
second = second->next;
}
*tmp = NULL;
}
while (first && second);
// Handle remaining Node that hasn't pointed by Last after while loop
*tmp = (first) ? first : second;
// Change first to what Third pointing at, which is First Node
first = third;
// Change last pointer from old first linked list to new last Node, after Merge
Node *p = first;
while (p->next)
{
p = p->next;
}
last = p;
// Destroy second linked list because every Node it's now connect with first linked list
// This also prevent from Double free()
b.first = b.last = NULL;
}
int main()
{
int arr1[] = {4, 8, 12, 14, 15, 20, 26, 28, 30};
int arr2[] = {2, 6, 10, 16, 18, 22, 24};
int size1 = sizeof(arr1) / sizeof(arr1[0]);
int size2 = sizeof(arr2) / sizeof(arr2[0]);
LinkedList l1(arr1, size1);
LinkedList l2(arr2, size2);
LinkedList l3(l1);
LinkedList l4;
l1.Display();
l2.Display();
l3.Display();
l4.Display();
// Merge two linked list, pass l2 as reference
l3.Merge(l2);
l4 = l3;
l1.Display();
l2.Display();
l3.Display();
l4.Display();
return 0;
}
Demo
There are several questionable practices applied in this code, and there is also a bug.
First, the bug. When you create a list, it news all its nodes and keeps track of them using pointers. When you assign a list to another, you literally copy the pointer values. Not only have you now lost the nodes of the assigned list (because you overwrote them) and got a memory leak (because now there's no pointer pointing to the allocated nodes), you also now have the same pointers on two different lists, pointing to the same nodes. When the lists are destroyed, both of them try to delete their nodes, and you end up freeing the same memory twice. Yuk.
The solution to this bug is to implement the assignment operator.
Then, the questionable practices:
using namespace std; (Why is "using namespace std;" considered bad practice?)
You're assigning the members of LinkedList in the constructor body, instead of passing the values directly to their constructor in the initialization list. (What is this weird colon-member (" : ") syntax in the constructor?)
Declaring an array parameter (int[]) is declaring a pointer. Just be aware of it.
new cannot return NULL! It's useless to check its return value. If it can't allocate, it will simply throw an exception.
NULL is the inappropriate constant to use. You can use nullptr, it's the C++ equivalent of NULL, except it's type safe.
Manual memory management with new and delete is tricky to get right (as you figured out yourself). You might be interested in using std::unique_ptr or std::shared_ptr to alleviate the burden. They would have caught the bug.
Now, please: do not write in C++ like it's C with classes. I understand that you may not have encountered all of the features I presented here, but anyway now you know about them :)

Segmentation fault while implementing linkedlists in c++

I am currently learning data structures, I was trying to create a function insert to insert a node at the nth position but I am always getting a segmentation error could you please help.
#include <iostream>
using namespace std;
struct node {
int data;
node* next;
};
struct node* head = NULL;
void insert(int dat, int pos) {
node* temp = new node;
temp->data = dat;
temp->next = NULL;
if (pos == 1) {
temp->next = head;
head = temp;
return;
}
node* newtemp = head;
for (int i = 0; i <= pos - 1; i++) {
newtemp = newtemp->next;
}
temp->next = newtemp->next;
newtemp->next = temp;
}
void print() {
node* temp = head;
while (temp != NULL) {
cout << temp->data;
temp = temp->next;
}
cout << endl;
}
int main() {
head = NULL;
insert(4, 1);
insert(6, 2);
print();
}
It should be
i<pos-1
temp->next=newtemp->next;
newtemp->next=temp;
And you should check if the Linkedlist have the position you have given
ie, if you pass to add node in 6th position to a Linkedlist having 2 nodes, it will give you segmentation fault.
By NULL->next
So you should check whether the linked list have the length less than or equal to position.
flag=false;
while(temp!=NULL)
{
if(i==Pos){
flag=true;
break;
}
temp=temp->next;
i++;
}
if flag is false then length is insufficient else do your stuff in temp
Look at this statement of insert() function:
for (int i = 0; i <= pos - 1; i++) {
For inserting element 6, you are giving positing 2.
First iteration:
initialize i with 0
0 <= 2 - 1 ==> true
newtemp = newtemp->next
[After this statement, newtemp is NULL because your linked list has only one element]
i++ ==> i is now 1
Second iteration
1 <= 2 - 1 ===> true
newtemp = newtemp->next
[newtemp is NULL and this statment will attempt to access next of a NULL
which is resulting in segmentation fault]
I hope you understood the cause of segmentation fault and a simple change can solve this problem - add NULL check for newtemp node, like this
for (int i = 0; i < pos && newtemp->next != NULL; i++) {
Your code does not check the validity of a pos value passed and with your current implementation it will add the element at the end of list if the pos value is greater than size of linked list. May you want to throw error when the value of pos is not valid. Also, you are not releasing the memory allocated for linked list nodes. Follow the good programming practice - release allocated memory before program exit.
Additional:
Since you are implementating the linked list in c++, you should use the object oriented concepts in you implementation. For e.g. bundle the data and functions operate on that data in one unit:
class Node {
private:
int data;
Node* next;
public:
// Add constructor for initialization of memeber variables
// Add destructor for cleanup and release memory
void insert(int dat, int pos);
void print();
};
A better implementation would be to separate the node and linkedlist in two different classes and bind their data with respective operations in them. For e.g.
class Node {
private:
int data;
Node* next;
public:
Node();
Node(const int& val);
void setData(const int& val);
int getData() const;
void setNext(Node* const nodePtr);
Node* getNext() const;
};
Singly linked list class LinkedList consisting of Node objects:
class LinkedList {
private:
Node* headNode;
Node* tailNode;
Node* currNode;
unsigned int count;
public:
LinkedList(); // constructor
// other overload of constructor, copy constructor, assignment operator, move semantics ....
~LinkedList(); // destructor
bool insertNode(const Node& newNode);
// other overload of insert, like insert at given position, at head of list, at tail of list etc..
unsigned int getCount() const;
Node* getHeadNode() const;
Node* getCurrNode() const;
Node* getTailNode() const;
bool deleteNode(const Node& node);
// other overload of delete node like detete tail node, delete head node etc.
bool deleteList();
};

Problem with insertion at a certain point in linked list with inherited functions in C++

I am trying to insert a number at a certain position in a linked list. However I cannot access the next pointer normally because it is a private member, and have to use a getNext function. I am unsure of how to assign next pointers with this function as it gives me errors.
#pragma once
class IntListNode {
public:
IntListNode(int e, IntListNode *nextptr):
elem(e), next(nextptr) { }
int &getElement() {return elem;}
IntListNode *getNext() {return next;}
private:
int elem; // linked list element value
IntListNode *next; // next item in the list
};
This is the code I have attempted but I keep receiving errors.
void IntegerList::AddAtPosition(int num, int placement)
{
IntListNode* temp1 = head;
IntListNode* temp2 = head;
temp1->getElement() = num;
if (placement == 0)
{
head = temp1;
}
else
{
for (int i = 0; i < placement - 2; i++)
{
temp2 = temp2->getNext();
}
temp1->getNext() = temp2->getNext();
temp2->getNext() = temp1;
//THe Lines getting errors
}
}
Error message:
E0137 "expression must be a modifiable lvalue"
Change your getNext() method to this: IntListNode*& getNext() {return next;}.
The IntListNode *getNext() version will return the value of next member but not it's address so this line is not modifiable: tempX->getNext() = tempY;
Edit
Based on the restrictions/conditions mentioned by the OP, I can think of only way to this is:
*temp1 = IntListNode(temp1->getElement(), temp2->getNext());
*temp2 = IntListNode(temp2->getElement(), temp1);

Trouble with insertion function for ordered linked list class in C++

I have a template class OList that is an ordered linked list (elements are ordered in ascending order). It has a function called void insert(const T & val) that inserts an element into the correct place in the list. For example, If I had an OList of ints with the values { 1,3,5 } and called insert(4), the 4 would be inserted between the 3 and the 5, making OList { 1,3,4,5 }.
Now, what I have works fine when inserting elements into EMPTY OLists. However, when I use the following code:
OList<char> list;
for (int i = 0; i < 3; i++) {
list.insert('C');
list.insert('A');
}
printInfo(list);
printList(list) should output:
List = { A,A,A,C,C,C } Size = 6 Range = A...C
Instead, it outputs:
List = { A,C,C,C,
followed by a runtime error.
I have been messing with this for about 5 hours now, but I don't seem to be making any progress (aside from getting DIFFERENT wrong outputs and errors).
There are three relevant pieces of code: OList's default constructor, operator<<, printInfo(), insert(), and a helper function for insert that finds the node to insert the element. I don't see any reason to provide operator<< nor printInfo() since these seem to work fine elsewhere.
// default constructor
OList() {
size = 0;
headNode = new Node<T>;
lastNode = new Node<T>;
headNode->next = lastNode;
lastNode->next = NULL;
}
void insert(const T & val) {
if ( isEmpty() ) {
lastNode->data = val;
}
else {
Node<T> * pre = headNode;
Node<T> * insertPoint = findInsertPoint(pre, val);
Node<T> * insertNode = new Node<T>;
insertNode->data = val;
insertNode->next = insertPoint;
pre->next = insertNode;
// why is pre equal to headNode?
// I thought I changed that when using it
// with findInsertPoint()
cout << (pre == headNode) << endl;
}
size++;
}
// returns the node AFTER the insertion point
// pre is the node BEFORE the insertion point
Node<T> * findInsertPoint(Node<T> * pre, const T & val) {
Node<T> * current = pre->next;
for (int i = 0; (i < getSize()) && (val > current->data); i++) {
pre = current;
current = current->next;
}
return current;
}
lastNode is simply the last node in the list.
headNode is a "dummy node" that contains no data and is only used as a starting place for the list.
Thanks in advanced. I'm really embarrassed to be asking for homework help on the internet, especially since I'm sure the main problem is my lack of a thorough understanding of pointers.
You are passing the pointer to pre by value into findInsertPoint, so it is copied, and the function changes the copy of pointer, and when the function returns, it is still the old pre, not the pre from inside the function.
If you want to change the pointer, you must pass pointer to the pointer to the function (or reference to pointer).