I have a fully working LinkedList that functions with int variables. I'm looking to change it work with objects, but I'm feeling stuck when it comes to pointers. Any advice?
This is the Node struct:
typedef struct Node
{
int data;
Node* next;
}* nodePointer;
And this is the AddNode function:
void LinkedList::addNode(int dataToAdd)
{
nodePointer nodeToAdd = new Node;
nodeToAdd->next = NULL;
nodeToAdd->data = dataToAdd;
if(head != NULL)
{
current = head;
while(current->next != NULL)
{
current = current->next;
}
current->next = nodeToAdd;
}//end if
else
{
head = nodeToAdd;
}//end else
}//end addNode
Is it a matter of a few simple changes?
It depends on the type of objects you will be using.
For any class where the default = operation makes sense, you could use the same code you have right now, replacing int with your object's type.
For a more complicated object (for instance, one holding a pointer to a dynamically allocated member), you would have to either define an appropriate = operator for this class or use a copy function to ensure that the object is properly copied
Related
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 5 years ago.
I have a simple implementation of a Linked list class, which has pointers to Node objects which I have also defined.
The function insertHead creates a new Node and inserts it at the head.
However, whenever I call the function, the constructor seems to return a pointer to the same object every time. (I checked that using GDB)
I am pasting snippets of the code here. Can someone please let me know if something seems off?
void LinkedList::insertHead(int val){
Node temp(val);
if(head == NULL){
head = tail = &temp;
} else {
temp.setNext(head);
head = &temp;
}
}
Class definitions:
class LinkedList{
Node *head;
Node *tail;
...
class Node{
int val;
Node *next;
...
Node::Node(int x){
val = x;
next = NULL;
}
You cant assign address of automatic storage variable and use it out of the body, becouse it got out of scope (undefined behaviour). You need to dynamically allocate space on heap for the node.
Node * temp = new Node(val);
if(head == NULL)
{
head = tail = temp;
} else {
temp.setNext(head);
head = temp;
}
And in destructor free all nodes.
You need to allocate your nodes on heap rather than stack. (I encourage you to read about those two). Also please use nullptr instead of NULL if supported ( > c++11)
void LinkedList::insertHead(int val){
Node* temp = new Node(val);
if(head == nullptr){
head = tail = temp;
} else {
temp->setNext(head);
head = temp;
}
}
This will also require you clean up the nodes properly using the delete to avoid memory leaks which will most probably require adding a custom destructor to your list class, something along those lines:
LinkedList::~LinkedList() {
Node* node = head;
while(node != nullptr) {
Node* toDel = node;
node = node->next;
delete toDel;
}
}
I keep getting a segmentation fault on my deep copy of a linked list. I use this deep copy in my Copy Contructor and my assignment operator (operator=) and have come to the conclusion that it is this that is seg faulting.
bigint::Node* bigint::deepcopy(bigint::Node* target){
bigint::Node* current = target;
bigint::Node*cpy = new Node;
cpy->digit = current->digit;
Node* const hd = cpy;
current = current->next;
while(current != nullptr){
bigint::Node* tmp = new Node;
tmp->digit = current->digit;
cpy->next = tmp;
cpy = cpy->next;
current = current->next;
}
return hd;
}
My Node struct looks like:
private:
struct Node{
int digit;
Node* next;
};
Node* head;
static Node* deepcopy(Node* target);
My class is closed and all, just showing what is in private that is related to this function. Thanks in advance for any advice.
When you use your deepcopy function, you must make sure that the paramater target is not nullptr. So, you should check if (target == nullptr) at the beginning of your deepcopy function.
Also, after the while loop finished, you should set the tail of your new list to nullptr.
From the information you post, it seems you have use ->digit or ->next on a null pointer.
If you still get this error, you'd better provide a example code.
I am learning list in C++ independently, and i have searched many websites about it. However, almost every approach to create a list is the same.
They usually create a struct as the node of a class. I want to create a class without using struct. So I created a class name ListNode which contains an int data and a pointer.
The main member functions of my class are AddNode and show.
Although, this program compiles successfully, it still does not work as I wish.
Here is the header file:
#ifndef LISTNODE_H_
#define LISTNODE_H_
#pragma once
class ListNode
{
private:
int data;
ListNode * next;
public:
ListNode();
ListNode(int value);
~ListNode();
void AddNode(ListNode* node,ListNode* headNode);
void show(ListNode* headNode);
};
#endif
Here is the implementation:
#include "ListNode.h"
#include<iostream>
ListNode::ListNode()
{
data = 0;
next = NULL;
}
ListNode::ListNode(int value)
{
data = value;
next = NULL;
}
ListNode::~ListNode()
{
}
void ListNode::AddNode(ListNode* node,ListNode* headNode) {
node->next = headNode;
headNode =node;
}
void ListNode::show(ListNode* headNode) {
ListNode * traversNode;
traversNode = headNode;
while (traversNode != NULL) {
std::cout << traversNode->data << std::endl;
traversNode = traversNode->next;
}
}
Main function:
#include"ListNode.h"
#include<iostream>
int main()
{
using std::cout;
using std::endl;
ListNode* head = new ListNode();
for (int i = 0;i < 3;i++) {
ListNode* Node = new ListNode(i);
head->AddNode(Node, head);
}
head->show(head);
return 0;
}
As far as I am concerned, the output should be
2
1
0
However, the output is a single zero. There must be something wrong in the AddNode and show function.
Could you please tell me what is wrong with these two functions?
When you call head->AddNode(node, head) you´re passing the memory directions which the pointers point, when the function arguments receive those directions, they are now pointing to the same directions, but those are another pointers, no the ones you declared in main. You could see it like this:
void ListNode::AddNode(ListNode* node,ListNode* headNode) {
/*when the arguments get their value it could be seen as something like:
node = Node(the one from main)
headNode = head(the one from main)*/
node->next = headNode;
/*Here you are modifying the new inserted node, no problem*/
headNode = node;
/*The problem is here, you´re modifying the memory direction
headNode points to, but the headNode argument of the function, no the one declared in main*/
}
So the pointer head in main() always points to the same first node you also declared in main().
In order to fix this you should change your code this way:
void ListNode::AddNode(ListNode* node,ListNode** headNode) {
/* second paramater now receives a pointer to apointer to a node */
node->next = *headNode;//the same as before but due to pointer syntaxis changes a bit
*headNode = node;//now you change the real head
}
And when you call it:
head->AddNode(Node, &head);//you use '&' before head
Now the real head, no the one in the function, will point to the last node you inserted.
So I'm creating a doubly linked list class and use a temp node to insert new values and whatnot. So I have a Node struct:
template <typename T>
struct Node
{
// Data in this node
T mData;
// Link to previous node
Node* mPrev;
// Link to next node
Node* mNext;
};
and I have the following member variables in the actual List class:
// Pointer to the head node
Node<T>* mHead;
// Pointer to the tail node
Node<T>* mTail;
// Pointer to current node
Node<T>* mCurr;
// Number of nodes currently in the list
unsigned mSize;
All this is kosher, given to me by my professor.
However, whenever I create a temp pointer to insert a new value, using the delete keyword crashes the program with an error "First-chance exception at ... Access Violation reading location...". Here is an example of the function I'm writing:
void insert_front(const T& value)
{
Node<T>* temp = new Node<T>;
temp->mData = value;
temp->mPrev = nullptr;
temp->mNext = mHead;
if (mSize == 0)
{
mTail = temp;
mHead = temp;
}
else
{
mHead->mPrev = temp;
mHead = temp;
}
mSize++;
//delete temp;
}
Now aside from the obvious memory leak, this function works as it's supposed to. But when I add a delete ANYWHERE, the whole thing crashes. Even if I cut out EVERYTHING except for the new line and the delete line, everything crashes. The only other files in the program were created by my professor and have no errors. What am I doing wrong?
Were I betting man I'd wager that temp pointer is now an integral part of your list rather than a simple place holder.
if (mSize == 0)
{
mTail = temp;
mHead = temp;
}
else
{
mHead->mPrev = temp;
mHead = temp;
}
When you delete temp you are deleting whatever mTail and mHead or mHead->mPrev and mHead are pointing to. When you try to access this deleted data you get undefined behavior which is usually a crash.
My mind is confused at the moment:
struct Node {
int data;
struct Node *next;
}
void Print(Node *head) {
}
This is a code snippet from HackerRank. While this is easy, I just started wondering something: If I modify the head in the Print function, does it modify the original head in the main as well, or is it just the local variable head that is modified?
You passed in a pointer by value, if you modify that pointer then it will not affect the original.
However if you modify what is pointed to by that pointer then it will affect the original.
For instance head = nullptr; would not, while head->data = 1; would.
Also note that any recursion you do will similarly change the original data, for instance an algorithm to add to the end of the list:
Node* previous = head
Node* current = head->next;
while (current != nullptr)
{
previous = current;
current = previous->next;
}
previous->next = new Node(); //However you create one.
Since it uses head->next and eventually modifies the result it will modify the original list.