struct node {
int data;
struct node* next;
}
void push (struct node **head, int data) {
struct node* newNode = malloc (sizeof (struct node));
newNode->data = data;
newNode->next = *head;
*head = newNode;
}
//I understand c version well.
C++ version
void Stack::push( void *data ) {
struct node *newNode = new node;
newNode->data = data;
newNode->next = head;
head = newNode;
}
In c++ head is a private or protected member of stack class and is declared as node *head.
Question: why head can preserve its value after push() call in c++.
In c, we need to declare it as ** since we want to change the value of head pointer after the push() function call. In c++ code, won’t changes to head be lost after the call?
The problem here is the C code you're comparing to C++ is not really analogous. A better example would be
typedef struct Node {
int data;
struct Node* pNext;
} Node;
typedef struct Stack {
Node* pHead;
} Stack;
void push(Stack* this, int data) {
Node* newNode = malloc (sizeof (Node));
newNode->data = data;
newNode->next = this->head;
this->head = newNode;
}
In this version we've successfully implemented push without having to take a ** for head. We have in a way because it's double indirected via the Stack*. But this is very similar to how C++ works. It's possible to view C++ as passing this as a hidden argument to the function.
In this case, since Stack::push is non-static, head is a shorthand for this->head. So the head = newNode is the same as:
this->head = newNode;
Related
class Node
{
public:
int value;
Node *next;
};
class LinkedList
{
private:
Node *head;
public:
LinkedList(void) { head = NULL; }
~LinkedList(void){};
void insertAtHead(int);
void insertAtLocation(int, int);
void Delete(int);
void displayList();
int countList();
};
void LinkedList::insertAtHead(int new_value)
{
struct Node *newNode, *NodePtr = head;
newNode = new Node;
newNode->value = new_value;
newNode->next = NULL;
if (!head)
head = newNode;
else
{
newNode->next = NodePtr;
head = newNode;
}
cout << "Node successfully inserted at the head\n\n";
}
I didn't create any structure for the node, rather I made a class for it. But I don't know why my code is working properly when I make a newNode in the insertAtHead function by writing struct at the start of initialization, What is happening there? no, compile and run time error when the struct is written before Node. What is the concept behind this work?
There is no difference between struct and class that is relevant to this code. So you can switch them around as you wish with no consequences.
This
struct Node *newNode, *NodePtr = head;
is a C-ism. In C++ you would write:
Node *newNode, *NodePtr = head;
Moreover a struct is a class in C++. struct and class are just two different keywords. Only for default access they make a difference when used to define a class. See here for more details on that: When should you use a class vs a struct in C++?.
I have a node in a linked list defined as:
class Node {
public:
Node* next = nullptr;
int value;
};
I am inserting nodes into the list as:
void insertNode(Node* &head, int value) {
Node* newNode = new Node;
newNode->value = value;
newNode->next = head;
head = newNode;
}
I want to remove some node in that list in another function
void deleteNode(Node* head) {
// ...
}
How can I remove that now unused node from memory?
You'd remove a node by 1) deleteing it. 2) adjusting the previous node to point to the one following the deleted node (or nullptr if the deleted node was the last one).
I'm trying to implement a singly linked list on my own in C++ from scratch, having got so far with my first method append():
#include <iostream>
using namespace std;
struct ListNode{
int key_value;
ListNode *next;
};
class List{
public:
List();
void append(int key);
private:
ListNode *head;
ListNode *tail;
};
List::List(){
head = NULL;
tail = head;
}
void List::append(int key){
ListNode *newnode;
newnode->key_value = key;
newnode->next = NULL;
if(head == NULL){
head = newnode;
tail = head;
}
else{
tail->next = newnode;
tail = newnode;
}
return;
}
int main(){
try{
List l1;
l1.append(1);
//l1.append(2);
//l1.append(3);
//l1.append(5);
}
catch (exception const& ex) {
cerr << "Exception: " << ex.what() <<endl;
return -1;
}
}
It compiles without any warnings or errors, but during execution I'm only getting the message Bus error: 10. Seems there is something wrong with the way I'm initializing and using the ListNode variables and pointers, any insights would be appreciated.
In this line:
ListNode *newnode;
you create uninitialized variable of pointer to ListNode and then you dereference it. Any access to unintialized variable leads to UB, but with pointers you most probably will get bus error immediatly. So allocate memory:
ListNode *newnode = new ListNode;
Note: instead of initializing data members:
newnode->key_value = key;
newnode->next = NULL;
you should provide proper constructor for ListNode:
struct ListNode {
int key_value;
ListNode *next;
ListNode( int v ) :
key_value( v ),
next( nullptr )
{
}
};
then just create it:
ListNode *newnode = new ListNode( key );
and next 2 lines can be omitted. This will make your code cleaner and prevent from creating a ListNode instance with uninitialized data.
Note N2: as your class List has a raw pointer and ownership of the data you should follow rule of three and create or disable copy ctor, assignment operator and dtor.
I'm creating a Linked List program and I currently have this method to insert an item into the front of the list:
template <class T>
void LinkedList<T>::insert(T *o)
{
node newNode;
newNode.o = o;
newNode.next = first;
newNode.prev = NULL;
first->prev = &newNode;
first = &newNode;
}
where I have a struct as follows:
struct node {
node *next;
node *prev;
T *o;
};
I think my logic is right for the insert method; however, I feel as if I'm not doing it properly, specifically dealing with the pointers. I feel as if I have to many newNode. lines and that I could do this better somehow. Any suggestions or is it right?
Note: I'm new to C++ so please be kind. I know this is a simple question
newNode is local to insert() and will be destructed when that method returns, meaning first->prev and first will be pointing to a node that no longer exists.
Use new:
template <class T>
void LinkedList<T>::insert(T *o)
{
node* newNode = new node;
newNode->o = o;
newNode->next = first;
newNode->prev = NULL;
first->prev = newNode;
first = newNode;
}
struct node* NewNode(int data)
{
struct node* node = new(struct node);
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
I am getting this error in first line of the function. Cant figure out whats wrong?
Thanks.
The "new" keyword hints at this being C++. In C++ the "struct TYPENAME" construct is largely obsolete, you can simply use TYPENAME instead.
The C way of typedefing a type name from a named struct is implicit in C++.
node* NewNode(int data)
{
node* pnode = new node;
pnode->data = data;
pnode->left = NULL;
pnode->right = NULL;
return(pnode);
}
should work just fine if this is C++. Please note that using the same name for a type and a variable is not a good idea. Some naming convention (hungarian or anything) helps.
This code compiles perfectly fine under Comeau try-it-out:
#define NULL 0
struct node
{
int data;
struct node* left;
struct node* right;
};
struct node* NewNode(int data)
{
struct node* node = new(struct node);
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}