I'm struggling with an issue. I have our regular node structure and a list that stores node pointers. When I'm trying to retrieve values fro such list using an iterator, I'm not able to do so...
#include <list>
#include <iostream>
using namespace std;
struct node
{
int data;
node* next;
};
int main()
{
node * n = new node;
n->data = 3;
n->next = NULL;
list<node*> l;
l.push_front(n);
list<node*>::iterator myIt = l.begin();
cout << *myIt->data << endl; // <-- the compiler shows an error here "Member reference base type "node*" is not a structure or union"
}
Perhaps I'm confused with the usage of iterators. Could you please suggest me a workaround?
Cheers!!!
Problem with operators precedence: use cout << (*myIt)->data << endl;
cout << *myIt->data << endl;
You need additionnal ()
cout << (*myIt)->data << endl;
Bye,
Francis
You are actually a bit confused, you need to do the following
cout << (*myIt)->data << endl;
You first have you dereference the pointer, then you can fetch the data.
Related
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;
I'm implementing a stack using GList (doubly) but when I assign my stack with the last element using g_list_last(*stack*) the program doesn't print my stack at all
Pointing to the first element using g_list_first(*stack*) works and I can traverse with stack->next pointer
Here's my test program:
#include <iostream>
#include <cstdlib>
#include <glib.h>
using namespace std;
int main()
{
cout << "Enter the no of random data to push: ";
int number = 0;
cin >> number;
GList *stack = nullptr;
for (int i = 0; i < number; i++) {
int data = random() % 10;
stack = g_list_append(stack, GINT_TO_POINTER(data));
cout << "Push: " << data << endl;
}
cout << "Printing the stack forward:\n";
stack = g_list_first(stack);
while (stack != nullptr) {
cout << GPOINTER_TO_INT(stack->data);
cout << "->";
stack = stack->next;
}
cout << "nullptr" << endl;
cout << "Printing the stack backward:\n";
stack = g_list_last(stack);
while (stack != NULL) {
cout << GPOINTER_TO_INT(stack->data);
cout << "->";
stack = stack->prev;
}
cout << "nullptr" << endl;
return 0;
}
Do I have to manually assign the prev link while appending?
First of all, I would not recommend using GLib in a C++ code base; GLib is a C library, full of idiomatic C code and functionality. I'd suggest using the C++ standard library, instead.
GList is a doubly linked list where each element is composed by three pointers:
typedef struct _GList GList;
struct _GList
{
void *data; // untyped pointer data
GList *prev; // pointer to the previous element in the list
GList *next; // pointer to the next element in the list
}
For convenience, all the GList functions accept a NULL as a valid list; in the case of g_list_append(), passing a NULL list as the first argument means that it will allocate a new GList element for the data you're passing and place it at the start of the list.
In your code you're taking the head of the list after populating it, and calling g_list_first(), which is a no-op on the head of the list; then you proceed to consume it by iterating over it, until you hit the end of the list, where you assign nullptr to the stack variable. Since nullptr/NULL is a valid empty GList, you're now calling g_list_last() on a valid, but empty list, which will return NULL, and thus prevent you from iterating backwards. Additionally, you're now leaking the memory allocated to the list.
The solution is to never iterate a GList with the same variable that holds the head of the list:
cout << "Printing the stack forward:\n";
GList *iter = g_list_first(stack);
while (iter != nullptr) {
cout << GPOINTER_TO_INT(iter->data);
cout << "->";
iter = iter->next;
}
cout << "nullptr" << endl;
The code above will consume the iter variable, instead of the stack. Which means that the code below:
cout << "Printing the stack backward:\n";
iter = g_list_last(stack);
while (iter != NULL) {
cout << GPOINTER_TO_INT(iter->data);
cout << "->";
iter = iter->prev;
}
cout << "nullptr" << endl;
will work appropriately, and walk the stack backwards, as the stack variable still points to the head of the list, and you're now consuming a temporary iterator.
Remember to call g_list_free() on the list to release any resources allocated for it—and g_list_free_full() in case you're allocating the contents of the data pointer as well.
I'm new to c++ and I'm facing an odd behavior from std::cout that I don't understand. In particular, when I want to print the value of the second node, using cout << nd.next[2]->next[17]->val, I get some convoluted bytes. However, if I set it to a variable first, e.g string let2 = nd.next[2]->next[17]->val, then use cout << let2, it prints the correct character. My code is below, I was implementing a trie. (Also since I am very new to c++ any other comments about what I am doing wrong in the code is appreciated)
#include <iostream>
#include <set>
#include <iterator>
#include <map>
#include <string>
#include <unordered_map>
using std::set;
using std::cout;
using std::endl;
using std::string;
struct Node {
Node* next[26];
string val;
void insert(string str) {
cout << "insert " << str << endl;
insert(str, 0);
}
void insert(string str, int idx) {
if (idx >= str.length()) {
return;
}
char cur = str[idx];
int curIdx = cur - 'a';
cout << "cur: " << cur << endl;
cout << "cur idx: " << curIdx << endl;
if (!next[curIdx]) {
Node newNode = Node();
newNode.val = cur;
next[curIdx] = &newNode;
}
next[curIdx]->insert(str, idx+1);
}
};
int plus(int a, int b) {
return a+b;
}
int main() {
Node nd = Node();
nd.insert("cryptography");
string let1 = nd.next[2]->val;
string let2 = nd.next[2]->next[17]->val;
cout << "first letter " << let1 << endl; // c
cout << "second letter " << nd.next[2]->next[17]->val << endl; // wrong
cout << "second letter " << let2 << endl; // work as expected
cout << "sum " << plus(1,2) << endl; // work as expected
// cout << nd.next[2]->next[17]->val << endl;
return 0;
}
Regarding the second part of your question ("what I am doing wrong"), in the insert() method you create Node() object on stack and assign next[curIdx] with a pointer to this object. But that stack object is destroyed automatically once the execution steps out of the scope where that object is defined, so next[curIdx] ends up pointing to garbage (memory where the object used to be before destroying).
Not sure how the next line is even working, next[curIdx] points to garbage at this point: next[curIdx]->insert(str, idx+1);
Instead you should allocate Node objects on heap with the new operator, ex:
if (!next[curIdx]) {
next[curIdx] = new Node(); // allocated on heap
next[curIdx]->val = cur;
}
but then you should make sure to deallocate (delete) them at some point to avoid memory leaks. Destructor of Node may be a good place for that – you can recursively delete all non-null Nodes from next array.
Also you could use smart pointers instead of raw pointers, they automatically delete objects when they can't be no longer accessed (garbage collector does that automatically in other languages like Java and C#).
More on stack vs heap: https://www.geeksforgeeks.org/stack-vs-heap-memory-allocation/
I've made a new node. How do I refer node->question->question, node->question->options[], node->question->correctans and node->question->difficulty_level
struct node {
node *prev;
node *next;
int count;
Question question[];
};
struct Question{
String question;
String[] options;
String correctans;
int difficulty_level;
}
I am not certain what you are asking but I think this is what your looking for:
#include <string.h>
#include <iostream>
using namespace std;
struct Question{
string *question;
string *options [4];
string correctans;
int difficulty_level;
};
struct node {
node *prev;
node *next;
int count;
Question *question[4];
}n;
int main(){
Question *q;
Question qu;
q->question = new string("This is a question"); // assign some values
q->options[0]= new string("The first option");
q->difficulty_level = 4;
qu.question = new string("another question");
qu.options[0]= new string("The second option");
qu.difficulty_level = 5;
n.question[0] = q;
n.question[1] = &qu;
//print the assigned values
cout << "Question 1 question: " << *n.question[0]->question << endl;
cout << "Question 1 Option 1: "<<*n.question[0]->options[0] << endl;
cout << "Question 1 dificulty: "<<n.question[0]->difficulty_level << endl;
cout << "Question 2 question: " << *n.question[1]->question << endl;
cout << "Question 2 Option 1: "<<*n.question[1]->options[0] << endl;
cout << "Question 2 dificulty: "<<n.question[1]->difficulty_level << endl;
}
'->' is a pointer dereference. Since you have an array of objects in your node (and not just pointer to them), the correct way to access those would be 'node.question[x]'. The same applies for your Question struct, i.e. node.question[0].question would yield the question string of the first question saved in this nodes array (if this was valid c code...).
Hope this helps, let me know if anything is unclear to you.
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