I have a question on linked list, and they defined a Node struct:
struct Node {
int data;
struct Node* next;
}
that i can't change, so i created new struct in oreder to succeed answering the question:
struct tmpNode{
int data;
bool visit = false;
struct Node* next;
} t;
now i'm trying to do the folowing code but it failed on the last line - the purpose is to create parallel list with the struct i created:
t.data = head->data;
t.visit = true;
t.next = head->next;
t = t.next;
what am i doing wrong?
Thanks
You are trying to assign incompatible types. Type of t.next is Node*, while type of t is tmpNode.
Related
Today I was taught Linked list in class and I wanted to implement it on my own.
Here's the part of the code that I wrote. Note that traverseLL traverses the Linked list and insertAtEnd inserts a new node at the end of the linked list.
I believe I can implement Linked list logic / methods / functions on my own. But my question is, inside insertAtEnd function when I create a newNode with the parameters - my data to be inserted, and nullptr (because inserting at the end), It inserts garbage values (or memory addresses maybe) in my node, ignoring the data passed to the constructor.
using namespace std;
#define NL '\n'
class Node {
public:
int data;
Node* next;
Node (int data, Node* nextPtr=nullptr) {
data = data;
next = nextPtr;
}
};
void insertAtEnd(Node* &head, int data) {
Node* newNode = new Node(data, nullptr); // <---- Issue in this line
// When I do as above, my linkedlist nodes always store garbage values and not the data being passed.
// However, when I un-comment the below line, I get the correct output.
// newNode->data = data;
if (head == nullptr)
head = newNode;
else {
Node* temp = head;
while (temp->next != nullptr)
temp = temp->next;
temp->next = newNode;
}
}
void traverseLL(Node* head) {
if (head == nullptr)
return;
while (head->next) {
cout << head->data << " -> ";
head = head->next;
}
cout << head->data << NL;
}
int main() {
Node* head = nullptr;
insertAtEnd(head, 10);
insertAtEnd(head, 20);
insertAtEnd(head, 30);
traverseLL(head);
return 0;
}
For example, the output for the above code when keeping newNode->data = data line commented, is :
16259544 -> 16258392 -> 16258392
But when I un-comment that line, my output becomes, which is intended:
10 -> 20 -> 30
Why is this happening? Even though I've defined my constructor, why is it not working?
I think the cause for this is the statement data = data in the constructor.
Reason for this:
Before executing the first statement of constructor, the member variables of the class are allocated memory and contain junk/default values, and when the statement data = data is seen the compiler changes the parameter but not the member variable.
As a result, you are seeing junk/garbage values.
To resolve this we can either explicitly specify the member using this or use member initialization syntax.
You can use any of the following workarounds.
Workarounds:
You can change your class constructor code like any of the below formats:
1.
class Node {
public:
int data;
Node* next;
Node (int data, Node* nextPtr=nullptr) {
this->data = data; // we are explicitly specifying which data to use
next = nextPtr;
}
};
class Node {
public:
int data;
Node* next;
Node (int d, Node* nextPtr=nullptr) {
data = d; // as the member variable and local variable are of different names, no conflict
next = nextPtr;
}
};
class Node {
public:
int data;
Node* next;
// use the member initialization syntax
// Here we are initializing the data while allocating memory itself,
// so answer is perfectly right!
Node (int d, Node* nextPtr=nullptr) : data(data), next(nextPtr) {}
};
More on the member initialization and constructor:
https://en.cppreference.com/w/cpp/language/constructor
How do C++ class members get initialized if I don't do it explicitly?
Hope this helps,
Thanks.
Wouldn't it be the same to just have an embedded object of the same structure that is not a pointer?
Struct Node
{
int data;
Node next;
};
//vs
Struct Node
{
int data;
Node * next;
};
No!
Having the following struct:
struct Node {
Node other;
};
Is illegal! Node doesn't have a defined size; the compiler can't build it correctly. A Node would contain a Node which would contain a Node.. wait what?
A pointer however is fine, it just points to a section of memory. When defining a pointer, the type that it points to doesn't have to be complete, it just has to defined.
struct Node;
int main() {
Node* a; // Fine, no errors.
Node b; // Incomplete type error
}
Looked at every similar question on this compiler error. The following minimized code reproduces the error and I cannot see what the issue is. From reading here on SO, suspect it's the return type node* (being a struct) is invalid, but what else to specify as the return type? Thank you.
Header file:
#include<cstdio>
#include<cstdlib>
class double_clist {
struct node {
int info;
struct node *next;
struct node *prev;
};
node *start;
node *last;
int counter;
public:
node *create_node(int);
double_clist() {
start = NULL;
last = NULL;
}
};
Implementation File:
#include<cstdio>
#include<cstdlib>
node* double_clist::create_node(int value) { // Error on this line.
counter++;
struct node *temp;
temp = new(struct node);
temp->info = value;
temp->next = NULL;
temp->prev = NULL;
return temp;
}
When it reaches node here, it hasn't seen that it is inside double_clist yet. You need to also preface that with double_clist::.
double_clist::node* double_clist::create_node(int value) {
Trying to design a simple linked list. Node declared as such:
class Node
{
public:
friend class CRevList;
Node() {m_next = 0; m_prev = 0;}
Node(const T &t) {m_payload = t; m_next = 0; m_prev = 0;}
T Data() {return m_payload;}
const T Data() const { return m_payload; }
private:
Node *m_next;
Node *m_prev;
T m_payload;
};
So m_next points to the next item in the list and m_payload holds its value. m_head is declared as this:
private:
Node m_head; // Head node
Incomplete function to put a new node at the front of the list with payload t:
void PushFront(const T &t)
{
Node *newnode = Node(t);
m_head.m_next = newnode;
}
The above should declare a new node with a payload of t, and set the m_head's next node to the new node. I'm not yet linking it to the rest of the list, just want to get at least 1 node working.
int GetFirst() //get value of first item in list.
{
Node *firstnode = m_head.m_next;
int payload = firstnode->m_payload;
return payload; //m_head.m_next->m_payload;
}
This is trying to get the first node in the list, fetch it's payload, and return... which gives a Seg Fault 11 error.
I'm pretty sure it's a problem with how I'm doing the pointers, and I have a general understanding of them, but having read documentation I'm still not sure how to approach the error.
Thanks!
Solved with the help of Jonathan Wakely:
PushFront needed to be
Node *newnode = new Node(t);
Additionally, there was an problem trying to access the private variable with
int payload = nextnode->m_payload;
I needed to use the public method
int payload = nextnode->Data();
I got a question about structs.. C++ is not language what I'm learning but I have a need to do exercise..
I have a struct like this:
struct List
{
int data;
List* next;
};
and I got class and methods with which I can add/remove/printout elements of the struct so for example to view elements I got method:
void Kopa::Print()
{
List *tmp = p;
while (tmp != NULL)
{
cout << tmp->data << endl;
tmp = tmp->next;
}
tmp.struktura;
}
The question is, how can I add and access new struct in List struct?
I guess it the struct will look smth like this but I don't understand how to access it with class methods..
struct List
{
int data;
List* next;
struct NewList
{
int data;
NewList* next;
};
};
First you have to declare a member of that structure, just like you declare other member variables:
struct List
{
struct NewList
{
int data;
};
NewList my_new_list; // Declare a member
};
Then you use it like any other member, just nest the member access as needed:
List l;
l.my_new_list.data = ...;
If you mean how to access the NewList structure inside List to declare a local variable, then you have to use the scope operator :::
List::NewList new_list;
new_list.data = ...;
This looks like an implementation assignment for linked list
Your struct looks like a node struct, not a list. So I will be using struct Node instead of List to avoid confusion.
I don't know where your p comes from, but it is essentially how you would create p in your function.
Node *p = new Node();
p->data = 1;
p->next = NULL;
now if you need to add a new one, do the same thing
Node *q = new Node ();
q->data = 2;
q->next = NULL;
//assign q after p
p->next = q;
You can also create a constructor in your struct
Node (Node *previous, int newData)
{
List *q = new Node ();
q->data = newData;
q->next = NULL;
previous->next = q;
}
make sure you call delete to clean up these pointers when you are done with them