Inserting into the front of a linkedlist - c++

I am having troubles with my code. the calling linkedlist does not seem to get "updated" with the values or they are not saved or something. Could use some help, Thanks.
template <class T>
void LinkedList<T>::insert_front(const T& x)
{
LinkedList* p = this;
LinkedList* tmp = new LinkedList(x,p);
p = tmp;
cout<<p->m_data<<endl;
cout<<tmp->m_data<<endl;
The calling function is
//TEST : Inserting 10 numbers to a
cout << endl << "TEST : Inserting 10 numbers to A" << endl;
for (int k=0; k<10; k++){
A.insert_front(k+1);
}
cout << A << endl;
cout << "Size of a = " << A.size() << endl;
I get an output of 1122334455667788991010
which is the tmp data value and the p data value each call
The values go to the code, and they are the right values, just when I go to print A nothing is shown just an empty list. Thanks, I'm new here but love the community.

Your design of the linked list and of the method are wrong.
In the method you defined local variable p and assigned to it tmp. After exiting the method this local variable will be destroyed. So nothing was occured with the list itself. Neither its data member was changed. Also there is a memory leak.
template <class T>
void LinkedList<T>::insert_front(const T& x)
{
LinkedList* p = this;
LinkedList* tmp = new LinkedList(x,p);
p = tmp;
cout<<p->m_data<<endl;
cout<<tmp->m_data<<endl;
You should split you class into two classes. The first one will define the node of the list and the second one will control operations withy the list and contain the head of the list as its data member.

Related

Reference returning blank value

I'm writing a linked list, and using my main function to test it. Here's my code:
#include <iostream>
using namespace std;
class LinkedList {
int value;
LinkedList* next;
public:
LinkedList(int valueIn, LinkedList* nextIn) {
value = valueIn;
next = nextIn;
}
LinkedList(int valueIn) {
value = valueIn;
}
int getValue() {
return value;
}
void addNode(LinkedList* node) {
next = node;
}
LinkedList& getNext() {
return *next;
}
};
int main() {
cout << "starting..." << std::endl;
LinkedList list1(1);
LinkedList list2(2, &list1);
cout << list1.getValue() << " --> " << list1.getNext().getValue() << std::endl;
return 0;
}
I expect the output to be 1 --> 2, but I get 1 -->. As far as I understand, getNext() should return a reference to another list (list2 in this case), but something seems to be going wrong. My debugging efforts show me that list2 does have the correct value 2 when it's initialized, but when it's referenced for the final output, it doesn't seem to have anything for value. I can't for the life of me figure out why this is. Could someone help me to understand?
You are insertin list1(which is actually a node) to the end of list2, not the other way around, yet you call getNext() on list1. You should change the code in main to the below:
int main() {
std::cout << "starting..." << std::endl;
LinkedList list1(1);
LinkedList list2(2, &list1);
std::cout << list2.getValue() << " --> " << list2.getNext().getValue() << std::endl;
return 0;
}
Please note that there are a couple of other things which would be better to change:
Create a list class and a Node class woud make things clearer
Initializing the pointer to be NULL(or nullptr from C++11) in the LinkedList(int valueIn) constructor
Return the pointer to the node in getNext() rather than copy the node
You are not getting a blank value. Actually your program is crashing when you are trying to call list1.getNext().getValue() as getNext() is returning reference to a NULL.
You are doing the opposite of what you want to do.
Your list2 is pointing to list1 and list1 is pointing to NULL.
You should change your code with this:
LinkedList list2(2);
LinkedList list1(1, &list2);
cout << list1.getValue() << " --> " << list1.getNext().getValue() << std::endl;

Trying to write my own linked list impementation in c++, code segfaults after hitting 3 elements in the list

I've been trying to write my own implementation of linked list, but the code segfaults when I try to access an the third element or anything after it. Adding elements doesn't segfault, but accessing does. I can't find the pointer error in my get() function.
Each node in the list stores data (of Template t) and a pointer leading to the next node. I have two functions for everything- one for the first element, and one for any subsequent elements. The get() function for the subsequent elements always segfaults. I have some debug messages in the function that spit out results I can't explain. For example, if I run a get() request for the second element, an then the third, the code doesn't segfault, but it does return clearly incorrect results. Debug messages I placed indicate the segfault occurs when the second element calls the function to check the third element, if it occurs at all. Try the code with and without the line cout << newList.get(2) << endl; and you'll get very different results.
One possible cause is the pointer storage- I have the get() function output the pointer of each element (except the first) as it cycles through, and compare them to the pointers outputted by the add() function, and and pointers for element 0 and 1 match, but 2 and beyond do not match, and I can't seem to figure out why that would be.
#include <iostream>
using namespace std;
template <class T> class myLinkedList{
T data;
myLinkedList<T> *next = NULL;
public:
myLinkedList(T input){
data = input;
}
void add(T input){
if(next == NULL){
myLinkedList<T> newItem(input);
next = &newItem;
cout << "adding to list, data is " << input << ", pointer is " << next << endl;
}else{
myLinkedList<T> nextEntry = *next;
nextEntry.add(input);
}
}
T getData(){
return data;
}
//the start of the get function, only used by the first entry in the list
T get(int entry){
int currentPosition = 0;
if(entry == currentPosition){
return getData();
}else{
//defrefrence the pointer anc check the next entry
myLinkedList<T> nextEntry = *next;
return nextEntry.get(entry, ++currentPosition);
}
}
private:
//this vesion is the hidden, private vesion only used by nodes other than the first one
//used to keep track of position in the list
T get(int entry, int currentPosition){
//cout << currentPosition << endl;
if(entry == currentPosition){
return data;
}else{
//derefrence the pointer and check the next entry
cout << next << endl;
myLinkedList<T> nextEntry = *next;
currentPosition++;
T output = nextEntry.get(entry, currentPosition);
return output;
}
}
};
int main(){
myLinkedList<int> newList(3);
newList.add(4);
newList.add(5);
newList.add(7);
newList.add(9);
cout << newList.get(2) << endl;
cout << newList.get(3) << endl;
return 0;
}
Results are clearly erroneous- program should spit oout two macthing sets of pointers, as well as the numbers 5 and 7 ( the list elements)
One of your main problems is here:
if(next == NULL){
myLinkedList<T> newItem(input); // <<<<<<<<<<<<<
next = &newItem;
cout << "adding to list, data is " << input << ", pointer is " << next << endl;
}
you allocate an item on stack inside the if scope. Then you make next to point to this item. But... lifetime of the item is bounded by this scope. As son as you exit the scope, this item does not exist any longer. You need to allocate it dynamically by 'new' or other methods.
I had a breakthrough! Following Serge's solution was helpful, but one more change was needed- rather than create a function reference in the else block of my add function,
eg
myLinkedList<T> nextEntry = *next;
nextEntry.add(input)
i needed to use the pointer directly, as in
next->add(input)
I didn't know my pointer/object syntax

c++, method to display content in hash table.Using double linked list

I am doing a hash table using double linked list.Since the code is long I am just posting the method I have problems with.
In my header file with my linked list class I have this method that would display the content of each node in my linked list.
void display()
{
for (node * p = head; p != NULL; p = p->next)
{
cout << p->data << endl;
}
cout << endl;
}
Then I have my .cpp file where I have my class hashTable but I am not sure how to display the content of each list by using the method in my header file with the hash table. In my case my table has a size of 10. This is what I tried:
void showTable()
{
for (int i = 0; i < size; i++)
cout << table[hash(i)].display() << " ";
}
The error I get is no operator"<<"matches this operands and also
binary'<<':no operator found which takes a right hand operand of type 'void' (or there is no acceptable conversion)
For reference this is my function hash
int hash(int x)
{
return x % (size);
}
For this to work, the display function must return a string or int.
Your display function returns void. That means your line of code is equivalent to:
cout << void << " ";
of course that makes no sense, as cout can only print strings and numbers.
I don't know all your code, but since display() already prints that node try replacing that line with:
table[hash(i)].display();

c++ Linked List losing data between functions

I am having a problem with pointers and scope. I am trying to maintain an array of linked lists of pointers to objects. When I try to push_front() in one function, it works. However, if I try to iterate through the list in another part of my program, the list no longer contains any data, and my pointers are bad.
This is part of my parseCommands function. the problem is when printList is called:
Administrator *adminPtr = new Administrator(); // create new Administrator pointer
//local variables...
string adminName; //administrator's name
int adminMNum; //administrator's M Number
string adminEmail; //administrator's email address
string adminTitle; // administrator's title
// read in & store data for new administrator
inData >> adminName; //read in data
adminPtr->setName(adminName); //set admin name
inData >> adminMNum;
adminPtr->setMNum(adminMNum); // set admin M Number
inData >> adminEmail;
adminPtr->setEmail(adminEmail); // set admin email address
inData >> adminTitle;
adminPtr->setTitle(adminTitle); //set admin title
// finished storing new administrator info
// add Administrator to list
cout << "Adding Administrator: " << endl;
cout << "in records office adminPtr/newPerson: " << adminPtr << endl;
universityList.addPerson(adminPtr); // call addPerson--hashTable
//universityList.printPerson(adminPtr); // print admin info using polymorphic method
//cout << "The load factor (alpha) is: " << universityList.getLength()/universityList.getMaxTableSize() << endl; // print alpha
universityList.printList(adminPtr->getMNum()); // print all items at table[loc]--breaks here
cout << endl;
The addPerson function where printList works fine:
template <typename T>
void HashTable<T>::addPerson(T newPerson) { //newPerson is a pointer to a person object
int loc; // array location provided by hashFunction
cout << "in hashtable newPerson: " << newPerson << endl;
loc = hashFunction(newPerson->getMNum()); // get loc
table[loc].push_front(&newPerson); // add to list at table[loc] passing address of pointer to person
printList(newPerson->getMNum()); // print all items at table[loc]--works here
size++; // increment size
} //end function
The printList function that works when called in addPerson, but not in parseCommands:
template <typename T>
void HashTable<T>::printList(searchKeyType key) { //print list of items held in array location
int loc = hashFunction(key); // get array location
if (table[loc].empty()) { // if list is empty
cout << "Can not print person M" << key << " NOT found" << endl << endl;
} //end if empty
else{
list<T*>::iterator iter; // stl iterator
iter = table[loc].begin();
cout << "in printList table[loc]begin " << *iter << endl; //print address of table[loc]begin.()--where iter points
cout << "in printList item in table[loc]begin " << **iter << endl; // print address of the pointer that iter points to
while(iter != table[loc].end()) { // for each item in the list
(**iter)->print(); // print person info using polymorphic method
++iter;
} //end for
} // end else
} // end printList
The print function:
void Administrator::print()const {
// print Administrator info
cout << " " << "Full Name: " << getName() << endl;
cout << " " << "M Number : "<< getMNum() << endl;
cout << " " << "Email Addr: " << getEmail() << endl;
cout << " " << "Title: " << getTitle() << endl;
}; // end print function
The hashTable class:
template<typename T>
class HashTable{
public:
HashTable(); // constructor
bool isEmpty()const; //determines if the hash table is empty
int getLength() const; // returns (size) number of Persons in table (accessor)
int getMaxTableSize() const; // returns tableSize (size of array)
void addPerson(T person); // adds new Person
void removePerson(searchKeyType key); // deletes Person from the HashTable
void printPerson(T person); // prints Person info
T getNodeItem(int mNumber); //returns person object (accessor)
void printList(searchKeyType key); //print list of items held in array location
private:
int size; // number of Persons in table
static const int tableSize = 1; // number of buckets/array size -- planning on using 70001--assuming 35,000 entries at once; largest prime > 2*35000
list <T*> table[tableSize]; // array of STL lists for chains
int hashFunction(searchKeyType searchKey); // hash function to return location (array index) of item
}; //end HashTable class
I pass adminPtr to addPerson, and it seems to add it to the list. Why am I losing the data when I return to the parseCommands function? Is it a stack vs. heap issue? Do I need "new" somewhere? There are a few extra lines in there where I was printing out the address of the pointers trying to figure out what's going on.
This was a programming problem for a class that I was unable to resolve. We had to simulate a hash table using an array of STL linked lists. We were not allowed to use vectors, maps, etc. The program involves an abstract base class (Person) with derived classes (Administrator, etc.) and a templated hash table class. There is one more class (RecordsOffice) that holds the hash table.
class RecordsOffice {
public:
RecordsOffice(); // default constructor
void parseCommands(string fileName); // function to parse commands from a file to maintain the StudentList
private:
HashTable <Person*> universityList; // creates empty hashtable
};
The problem is in these two places.
universityList.addPerson(adminPtr);
//...
You are passing a copy of adminPtr.
template <typename T>
void HashTable<T>::addPerson(T newPerson) { //newPerson is a pointer to a person object
// ...
table[loc].push_front(&newPerson); // add to list at table[loc] passing address of pointer to person
// ....
}
newPerson is a local variable to addPerson. When it returns it is no more valid. But you are adding it´s address in to the table.
the issue is that
list <T*> table[tableSize];
is storing pointers to pointers of Person.
I don't think passing by reference would solve the problem too. Because then you will be dependent on the automatically created pointer here.
Administrator *adminPtr = new Administrator();
What adminPtr pointer points to will stay but not adminPtr itself. So you can not depend on its address (unless you are sstill in the same function that created it). One possible way to solve it would be to allocate adminPtr itself dynamically.
Administrator **adminPtr = new Administrator*;
adminPtr = new Administrator();
But maybe you should revise the requirements.
Your table is declared like this:
list <T*> table[tableSize];
That means any pointers it contains need to be dynamically allocated, or need to remain in scope for the entire lifetime of the container. This is not the case. In your function addPerson you add the address of a local variable:
table[loc].push_front(&newPerson);
You should do one of the following:
Change the table to an array of list<T> objects.
Copy the data dynamically. eg table[loc].push_front(new T(newPerson))
Because this is a list, I would go for option 1 because the list will copy locally anyway, and you won't have to clean up the pointers later. A third option would be to use list<unique_ptr<T> > or similar.

Can't get constructor to run

I'm trying to create a doubly linked list where each list has a first node, last node, and num_elements. However, for some reason, when I try to test the code in a UseList.cpp file, I can't get the num_elements to set to zero as default.
Let me show you what I mean:
In List.h:
template <class L>
class List
{
private:
Node<L> *first;
Node<L> *last;
int num_elements;
public:
// constructors and destructors
List();
[...]
}
[...]
template <class L>
List<L>::List() {
first = NULL;
last = NULL;
num_elements = 0;
}
[...]
This is the show method lower down in list.h:
template <class L>
// Print out the data in each node separated by a space.
void List<L>::show() {
cout << num_elements << endl;
Node<L> *current_node = first;
while (current_node != NULL) {
cout << current_node->data << " ";
current_node = current_node->next;
}
cout << endl;
}
Note that there is a cout statement there to print the num_elements.
This is the relevant part of UseList.cpp:
int main (int argc, char *argv[]) {
cout << "-----------------------------------------" << endl;
cout << "----------------LIST ONE-----------------" << endl;
cout << "-----------------------------------------" << endl;
List<int> *list1;
srand(time(NULL));
list1->show();
[...]
When show is called, it prints out "1" and gives me a segmentation fault. Why is num_elements defaulting to "1" instead of "0"?
When I do a cout in List<L>::List() {, nothing is printed... (this implies that the constructor never runs?)
Thanks for the help!
You are declaring a pointer to a List<int> and not initializing it to anything.
You have created a pointer to a List<int> object, but no object. So, currently, your program will segmentation fault because the pointer is "dangling". When you try to dereference it with ->, you are accessing memory that isn't yours, and it fails. To fix this, simply allocate a new List object:
List<int> *list1 = new List<int>();
Don't forget to free it later:
delete list1;
Your other option is to just not use dynamic memory. You shouldn't use it if you don't have to.
List<int> list1;
list1.show()
List<int> *list1;
Declares list1 to be a pointer.
List<int> *list1 = new List<int>();
Would actually create an instance of List