I found this C++ linked list implementation in Geeks for Geeks. For the code Click here
Here from line no. 16->22 it is written
Node *head = NULL;
Node *second = NULL;
Node *last = NULL;
head = new Node();
second = new Node();
last = new Node();
I understand
Three pointers are initialized with value NULL and then later three
instances of the class are created.
But what I don't understand is
Where the class objects are created and
From where the pointers are getting the addresses to point to.
And if I keep any data in private how to access it later then in this implementation because . operator is giving error
Where the class objects are created
The allocating new-expression acquires the memory from the free store.
From where the pointers are getting the addresses to point to.
The new-expression returns the pointer to the object that it created.
how to access it later
By indirecting through the pointer using an indirection operator.
Related
I'm working with LinkedLists from custom node, I'm still struggling to understand some concepts. For simplicity functions are reduced
class Node {
public:
T data;
Node* next;
Node(const T& copy){
data = copy;}
class T {
string name;
int age;
T(string name, int age){
T::name = name;
T:age = age;}
class LinkedList{
private:
Node* head;
void insertAtFront(string name,int age){
Node* newNode = new Node(name,age);
head = newNode;
/*
T temp(name,age);
Node newNode(temp);
head = &newNode */
;
}
I'm coming from java background, I know variables are treated differenly in c++ and java. I know c++ copies by value unless *, & is used. My misconceptions might probably occur because of the differences though, I couldn't solve it.
1-In insertAtFront function, implementations on the internet creates the node pointer dynamically(using new keyword). Can't we do it as the way between /* */ ?
2- I actually dont get the idea of why head is a pointer in the linked list. I've created linked lists in java. As long as the next value of the head is correct (so changing it in the correct way in c++) why should I make head a pointer ?
If you use:
T temp(name,age);
Node newNode(temp);
head = &newNode;
the variable newNode is destroyed when it goes out of scope. Then head points to a destroyed variable. It might continue to hold the same node values for a very short time - probably until the next function call (you can't rely on this). Then that memory space will be reused for some other variable.
head continues pointing to the same memory address, and the data at that address has been overwritten for some other purpose, so you won't be able to read the node data there that you want to read.
Each time you use new it creates a nameless "variable" that doesn't get destroyed and reused until you use delete. Since the variable doesn't have a name, you have to use pointers to refer to it.
2- I actually dont get the idea of why head is a pointer in the linked list. I've created linked lists in java. As long as the next value of the head is correct (so changing it in the correct way in c++) why should I make head a pointer ?
In Java, every Node variable - every object variable - is actually a pointer. In C++, that's not true and you have to ask for pointers when you want them. When you write Node next; in C++ you are saying that the variable next has a real, bona-fide Node inside the variable. If you write class Node {Node next;} then you are saying every node has another node inside it - but that one has a node inside it too - but that one has a node inside it too - on to infinity - which is impossible, of course.
You could choose to use Node head;. That's a valid design choice, but it complicates things. It means the first node in every linked list is inside the list itself, and you can't change which node it is because it's not a pointer. If you wanted delete the first node, then you'd have to do it by copying the second node to the first node and then deleting the second node. And you'd have to figure out how you wanted to store an empty list.
In a linked list that uses
struct Node {
T value;
Node* next;
}
For every used new operator (new Node()), there must be a delete operator.
An example of a destructor for such a list
~LinkedList(){
Node* tmp = head;
while(tmp! = nullptr){
delete tmp;
tmp = tmp->next;
}
}
My question is, what exactly gets "deleted" that allows me to use next pointer
even after delete is used? Does it only delete the value? How does that actually look in the memory?
In C++ when you delete an object on the heap nothing actually gets cleaned up, it just marks the memory as "free". This means that another call to new or malloc may overwrite that memory.
Accessing a deleted pointer is undefined behaviour because their are no guarantees on the data that resides there. I'm not very well versed in how the OS handles memory but I believe it could even be the case that your program no longer owns that page if that was the last item you deleted from that section of memory. If this happened to be the case then dereferencing that pointer will cause a segmentation fault on most desktop OS's.
If you wanted to safely move the head you should assign a temporary value to the next item while the pointer is alive, then you can delete the underlying object from memory.
When a data is deleted the pointer becomes undefined and for sure does not reach to memory it was pointing before, therefore there is no way to call tmp=tmp->next' after deletion.
The proper destructor declaration would be:
~LinkedList()
{
while (head != nullptr)
{
Node * tmp = head->next;
delete head;
head = tmp;
}
}
BTW.: Please read some good books on how to implement lists.
BTW.2: Use some standard containers like vector or list if you really need it.
These two pieces of code are creating very different results depending on the compiler and I don't understand why
node *active_node = new node;
vs
node current_node;
node *active_node;
active_node = ¤t_node;
From my understanding, I am manually creating a node object and assigning it to the active node pointer, same as the dynamic allocation above. However, they produce entirely different results in context of the program
In this code:
node *active_node = new node;
You are allocating a node object in dynamic (heap) memory, and then assigning its address to active_node. The node object will live until the program is terminated, or until you delete it.
In this code:
node current_node;
node *active_node;
active_node = ¤t_node;
You are allocating current_node in automatic (stack) memory, and then assigning its address to active_node. The current_node object will die when it goes out of scope (end of the function, etc), leaving active_node to point at invalid memory.
I'm trying to implement a BST in C++, and I came across these two ways of creating a node:
node* z = new node();
z->key = d;
z->left = NULL;
z->right = NULL;
and then this:
node* y = NULL;
node* x = root;
node* parent = NULL;
What is the difference in calling the new operator or not?
EDIT
so for example, whats the difference between:
node* q = new node();
and
node* q;
and why would you choose one way or the other? Is there an advantage for one way or the other?
To answer the question in the comment, yes there is a difference.
When you do node* q = new node() you declare a pointer to a node object, and then at runtime dynamically allocate memory enough for one node object, and calls the default constructor (alternatively, value initializes the object, it depends on the class/struct), and finally you assign the pointer to the newly allocated object to q.
When you do node* q; you just declare a pointer to a node object, and that's it. What the pointer will be pointing to depends on where you declare the pointer: If you declare it as a global variable, it is initialized to zero, and becomes a null pointer; If you declare it as a local variable its value is indeterminate, and will in reality seem to be random. Neither is a valid pointer, and dereferencing it will lead to undefined behavior. There is also a third alternative, and that's where you declare node* q; as a member variable in a class or struct, then the initial value depend on how the class/structure is created and initialized (for example if the structure is value initialized, if there's a constructor that initializes it, etc.).
I'm pretty sure (Someone correct me if i'm wrong), using the new operator allocates dynamic memory for that variable. The variables will most likely already have some garbage value assigned to them that gets overridden when you assign a new value to them. Whereas assigning it NULL just assigns it whatever the NULL value is (probably 0000000).
for this structure
struct node{
int no;
node *next;
};
what is the difference between these two types of declarations?
node *New=new node;
and
node *New;
node *New=new node;
This is initializing the pointer which is good thing to remember.
Whereas
node *New;
not which is a bad thing as chances of de-referencing it in it's naked form are there.
node *New=new node;
Creates a variable called New and initializes it with pointer, returned by operator new
node *New;
Depends on context, for namespace (global) context creates a variable, initialized by nullptr, or for local creates one uninitialized.
You should always initialize a variable when declaring it so that you know it is a good know state. when working with pointer either grab "new" memory at the time of the pointers creation or use nullptr.
node * New = new node; // Okay. We know New holds a good node and we can call delete on it
node * New = nullptr; // Okay. We know we can delete on it without crashing
node * New; // Bad. We dont know what the state of New is and we can't call delete on it
Both nod *New = new node; and node *New; are invalid declaration types. The reason why it allows the lines at all is because the programmer has declared a keyword as a declared structure. They are both bad lines of code. What you have so far is a pointer to a new structure(but not really). New is a keyword that instantiates an object that is greater in precedence than the current scope of the code block. Whenever an object is made eventually it must be unmade with the delete keyword.