Why is the output of this code always the same? - c++

Why am I getting the same output in the following for loop in c++.
node* nn = (struct node*)malloc(sizeof(struct node));
for(int i=0;i<10;i++)
{
node* n = (struct node*)malloc(sizeof(struct node));
cout<<&n<<endl;
nn->next = n;
nn =n;
}

Because your n variable is local to the loop body, it is created at the beginning of each iteration, and destroyed at the end of each iteration.
Evidently the compiler decided to reuse the same storage for every incarnation of n, which is why all of them have the same memory address.
Note that &n is the address of n, not its contents. You don't even have to initialize it. Your call to malloc is irrelevant.
If you want to see the value of n, you need to remove the &.

You're outputting &n which is the address of n not the content of n which is probably what you wanted.
NB: The question was edited following my answer, but the same problem remains.
Try this:
#include <iostream>
#include <cstdlib>
struct node {
node* next;
};
int main() {
node* nn = (struct node*)malloc(sizeof(struct node));
nn->next=nullptr;//Initialise so we can clean up nicely...
for(int i=0;i<10;i++)
{
node* n = (struct node*)malloc(sizeof(struct node));
n->next=nullptr;//Initialise so we can clean up nicely...
std::cout<<&n<<"=="<<n<<std::endl;
nn->next = n;
nn =n;
}
//Clean up after ourselves. Not relevant to the question but good practice.
while(nn!=nullptr){
node*n=nn;
free(nn);
nn=n;
}
return 0;
}
Typical output:
0x7ffda1be2058==0x55ffb0b9fc20
0x7ffda1be2058==0x55ffb0ba0c50
0x7ffda1be2058==0x55ffb0ba0c70
0x7ffda1be2058==0x55ffb0ba0c90
0x7ffda1be2058==0x55ffb0ba0cb0
0x7ffda1be2058==0x55ffb0ba0cd0
0x7ffda1be2058==0x55ffb0ba0cf0
0x7ffda1be2058==0x55ffb0ba0d10
0x7ffda1be2058==0x55ffb0ba0d30
0x7ffda1be2058==0x55ffb0ba0d50
The actual output may vary and in principle a compiler isn't required to store n at the same address each iteration. I know of no compiler that doesn't. Anyone?
NB: Using malloc() in C++ is very rarely recommended. The direct substitute for malloc() and free() is new and delete. In practice use std::unique_ptr<> or other self managing construct.

This is only an addition to melpomene's answer, responding to the comments:
How do I create n nodes? Use of vectors is prohibited, so I am creating a linked linked list of n nodes, but the problem is I am unable to create n nodes in a loop.
Actually, your code was less incorrect than you thought, solely you missed one important point:
nn->next = n;
With this instruction, you lost the last reference to what nn pointed to originally and you won't ever be able to re-gain it again...
What you yet need is a second pointer to the element created initially, so you don't lose your list head and thus the rest of the list any more:
node* nn = new node(); // this is the C++ way...
node* head = nn; // now you have a second pointer to the head...
for(int i=0;i<10;i++)
/* [...] */
Now you can access all the nodes you created via the head pointer (as long as you do not move it away from...).
Get rid of the loop and simply use struct *n = malloc (sizeof *n * 10); – David C. Rankin
Another variant: creating 10 elements directly... Assuming node looks like this:
struct node
{
Data data;
node* next;
};
Then you get 10 elements of Data simply by
Data* allData = new Data[10]; // again using the C++ way...
The C++ aproach has another advantage: the elements in the array are already initialised as the default constructor gets called (for primitive data types, see here).

Related

A little double-linked list puzzle

Disclaimer
So initially when I posted this, it was a forward list by my error even though I meant to do it as a double-linked list - that's why there are some replies that don't match the problem.
Problem
I was doing some coding and I got to code below. At first glance, it looked like there is nothing wrong with the code, but there is a logical flaw. Can you find it?
class Node {
int val;
Node *next, *prev;
public:
Node(int val, Node *prev, Node *next) {
this->val = val;
this->prev= prev;
this->next = next;
}
int get() {return val;}
Node* getNext() {return next;}
Node* getPrev() {return prev;}
};
int main() {
Node *n1, *n2, *n3;
n1 = new Node(1, NULL, n2);
n2 = new Node(2, n1, n3);
n3 = new Node(3, n2, NULL);
Node *next = n1;
while (next != NULL) {
cout << next->get() << endl;
next = next->getNext();
}
}
The problem is that pointers n1, n2, n3 will get the right addresses only after the memory is allocated with operator new. That means addresses of these pointers are not the same upon Node class instantiation. Eg. in line n2 = new Node(2, n1, n3); n3 would be a bad pointer (because the memory has not been allocated jet and is currently pointing to some nonsense).
Question
Fixing the problem is not an issue, but it made me wonder:
Can you find a way of fixing it without adding any new attribute or method to the class Node?
To go a step further, can you find a way of fixing it without changing any code inside the class Node?
My take on it
To the first question, I thought of the quickest solution. I just made attributes next and prev pointers to pointers and changed the code so that it passes references to the constructor. Also had to change the syntax of the while loop to get dereferenced values.
To the second question, we got one possible solution in replies. We can simply make an array of Nodes. This way we know the exact address of each member as n-th member of an array will have an address of the first member + n - 1;
Eg. in line n2 = new Node(2, n3); n3 would be a bad pointer
There is a simple solution. Fix the order of initialisation so that you start with objects that have no dependencies, and initialise objects after their dependencies have been initialised. In this case, "1" depends on "2" and "2" depends on "3", so therefore:
n3 = new Node(3, nullptr);
n2 = new Node(2, n3);
n1 = new Node(1, n2);
Is it possible to allocate memory in advance?
Sure. It is possible to allocate memory. If you allocate memory before doing something else, then you are allocating memory in advance of that something.
You could create all of the nodes in one go by using an array. You don't even need any dynamic allocation:
Node nodes[] {
{1, nodes + 1},
{2, nodes + 2},
{3, nullptr},
};
Node* next = nodes;
P.S.
I recommend against bare owning pointers. Your example leaks memory.
Don't use NULL in C++. It has been obsoleted by nullptr.
For whatever reason, you've forgotten to initialise the prev member.
I think changing to use pointers-to-pointers is a very very bad idea, and would be extremely odd.
The easist way to do this is to build the tree in reverse:
Node * n3 = new Node(3, nullptr);
Node * n2 = new Node(2, n3);
Node * n1 = new Node(1, n2);
This eliminates n1 using n2 before n2 is created.
However, you still have a problem. At no point are you managing prev. So you might want to do this:
Node(int val, Node *next) {
this->val = val;
this->next = next;
// Add these lines.
if (next != nullptr) {
next->prev = this;
}
}
Note also that using NULL to reference an uninitialized pointer is very old-style C. If you're going to program modern C++, please use nullptr instead, as you see in my examples.
I also did one more change different from yours. I personally don't like this code:
Node *n1, *n2, *n3;
I dislike it for two reasons, both of which will be referenced in at least some corporate style guides. First, some style guides will tell you to reference only one variable per line, not three, like you have. And also, some guides will warn you against leaving your pointers uninitialized. So I broke it out, as you see in my example above.
This last part is just style, but I can't tell you the number of bugs I've chased down due to one or the others of these. For instance, this can hide:
Node *n1, n2, *n3;
Depending on your font size, the sharpness of your eyes, and the phase of moon, you might not see that n2 isn't declared as a pointer. Now, modern compilers will probably catch bad usage, but still... Also, if you agree that all variables should be initialized to something reasonable when created, then your code can get lengthy, and it can be easy to not see you didn't initialize everything.
Seems like you are trying to create a doubly linked list. The bug is you have passed null inside the constructor as an argument. This can be resolved if you allocate memory in the following order:
Node *n3=new Node(3,NULL);
Node *n2=new Node(2,n3)
Node *n1=new Node(1,n2)
Node *next=n1
while(next!=NULL){
cout<<next->get();
next=next->getNext();
}

Understanding linked list with C++?

I get the idea of linked list being some kind of way of navigating through some kind of array/list/vector of sorts. I don't think i have the full idea of the concept. I've seen some charts explaining them but I don't seem to understand how they work. So I thought actually looking at the code might help. (My professor doesn't really go over the code that much)
I copied this code from some video.
#include<iostream>
using namespace std;
struct node
{
int num;
node *link;
}*p; // i'm not sure how this pointer was declared
void main()
{
node *root;
root = new node;
root -> num = 5;
root -> link = p;
p = root;
node *q;
for (q = p; q != NULL; q = q -> link)
{
cout << q -> num << endl;
}
}
I guess I don't know what the -> operator does exactly. I know it has something to do with pointers and I'm not sure how that for loop is working.
If someone could take me through the code or if they may have a better example to show me and also if there is any more info that I should know please tell. It would be appreciated.
I think the code is slightly incorrect (or maybe just bad style since it relies on the fact that the pointer is NULL after initialization) as is but I will try to explain this in detail.
Firstly the -> operator evaluates to a dereference followed by a dot ., so root->num is equivalent to (*root).num.
A linked list (in your case a singly linked list) is a structure like follows
NODE{1} --> NODE{3} --> NULL
Here a node is a struct object and has a pointer to another object. These objects together constitute the linked list. As you can see you need some sort of pointer to point to the first element in the linked list. In the example above that element would be the node with the 1 stored in it. This is the root pointer that you have in your code above.
The new is an allocation. You need to place the objects of your linked list somewhere in memory and the new operator helps you find some place in memory (particularly somewhere on the heap) you can store your object. And then it returns a pointer to this location. The best way to learn more about the heap is to research this online. This is an introductory concept (with a lot of "upper level" concepts at the implementation level but you do not have to worry about that at the moment) that is explained very well online. This will likely be better than reading my explanation so I will not explain more about the heap and the stack here. However I think the following links should be helpful
http://www.cplusplus.com/doc/tutorial/dynamic/
http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html
http://www.tutorialspoint.com/cplusplus/cpp_dynamic_memory.htm
You also need to know where to stop in the linked list, i.e. you need to know which element is the last element. In the case above the last element is the node with the 3 in it. So this node will not point to another Node object but will rather point to NULL, 0 or the preferred nullptr in C++11 and C++14 (soon also C++17). So you could construct the linked list above with the following code.
#include <iostream>
using std::cout;
using std::endl;
struct Node {
int element;
Node* next;
};
int main() {
Node* root = new Node;
root->element = 1;
root->next = new Node;
root->next->element = 3;
root->next->next = NULL;
for (auto i = root; i != NULL; i = i->next) {
cout << i->element << endl;
}
return 0;
}
Does that make sense?

Linked Lists with vectors

I am trying to perform certain operations through linked lists on vectors.
We have been given a struct type vector
typedef struct{
int *array; // a pointer to vector's storage
int size; // the current number of elements in the vector
int cap; // the current capacity of the vector;
int init_cap; // the initial capacity the vector was initialised with.
} vector;
Now, I want to make a function that takes in a pointer to the vector struct, and initialises it with the given capacity. All the fields are to be initialised. I want to do this using linked list.
Here is my code
#include <iostream>
using namespace std;
typedef struct node {
int *array; // a pointer to the vector's storage
int size; // the current number of elements in the vector
int cap; // the current capacity of the vector
int init_cap; // the initial capacity the vector was initialised with
node *next;
} vector;
node *head = NULL;
Can I make nodes from a vector struct, like I have attempted in the code written above?
void vector_init(vector *v, int capacity){
//initialising the vector with the given capacity
v->size = capacity;
v->cap = capacity;
v->init_cap = capacity;
//linked list with nodes created and values initialised
node *temp, temp2;
temp = head;
temp = new node;
temp->size = capacity;
temp->cap = capacity;
temp->init_cap = capacity;
temp->next = temp2
temp2 = new node;
temp2->size = capacity;
temp2->cap = capacity;
temp2->init_cap = capacity;
temp2->next = NULL;
}
Have I made the linked list, and initialised the values correctly? If we do not create temporary points temp and temp2, and just use v->size etc to initialise the fields, would that make it a linked list?
You have many problems with your code.
Don't use the name vector - there is a structure called std::vector and it is easy to get confused.
If you want to initialize the values of the structure, don't create an external, separate function for that - it's not c++'ish. Create a struct constructor initializing all the values instead.
You don't initialize the array variable anywhere in your code. You should allocate space for it depending on the capacity given in the constructor.
Don't use the name 'array' for the variable. There is a structure called std::array in C++, and it might be confusing.
Your implementaion makes very little sense to me. You have a linked list of arrays right now; if you would like to functionally replace an array of ints with a linked list of ints, each node should contain one int value.
If, for some reason, you would want to stick to this implementation, you also need some kind of update function that would automatically update size and cap variables while adding or removing elements from array. Otherwise you are sure to end up forgetting about it and you're gonna have mess in your structure. Make this function a part of the structure - it shouldn't be an external function.
That typedef struct node doesn't make sense even after changing the word vector to something else - you don't use it anyway in your code.
You are using the same name for two different structures; vector is at first defined as having 4 fields, and in the next lines as having 5 fields.
Technically yes, this is a linked list, but your vector_init() function does not work as it should. Apart from what I've written above:
You should avoid making functions depend on the global variable, in this case head. It could be passed as a parameter.
These two lines:
temp = head;
temp = new node;
don't make sense. The first one makes the variable temp point to head; the second one tells temp to start pointing to the new variable as you're using operator new, which allocates space and return a pointer to the newly created variable. As a result, you don't operate on the variable head, when you do further operations, but on another variable that will be lost after the temp pointer gets invalidated.
You don't need temp and temp2 variables at all. They only bloat the code.
These two lines:
temp->next = temp2;
temp2 = new node;
should switch places since now you assign a pointer that hasn't been yet initialised.
After writing all this stuff I've realised that the function is incorrect in general. For some reason, you first work on the parameter v, and then do something unrelated to it.
Also, your instructor is just not right saying that you can solve all types of problems with the use of linked lists. It may solve some problems in certain situations, or create new problems, depending on the context.
I don't want to be rude, but there seems to be something fundamentally wrong with the concept of the task you have been given itself. I guess someone really hasn't thought it through.

linked list first member variable of node structure always next node

Suppose you have a linked list of nodes as defined below:
C++ code
struct node {
node *next;
int i ;
};
Is there any benefit in making the next pointer as the first member variable of the structure ?
I think that people try this via the above approach (I may be wrong here)
node n, m;
*n=&m;
If above is right, is it right to code like above. What's the right way?
Is there any benefit in making the next pointer as the first member
variable of the structure ?
A very small performance benefit can be reached to reduce the assembly instruction size in loads from and writes to zero offset members, but only in classes without virtual table (vtbl is a omitted first member).
If you want prebuild a scope/global allocated list, its elements can be initialized as mentioned.
You can try it:
struct node {
struct node* next;
int i;
};
node z = {0}, c={&z}, b={&c}, a={&b};
node * stack = &a;
you can find very useful information about liked list searching for 'linux kernel linked list':
Linux Kernel Linked List Explained
How does the kernel implements Linked Lists?
I working now in my own design of 'intrusive node' general purpose containers using c++ templates, perhaps this question might seem interesting.
node n, m;
*n = &m;
is not legal code, perhaps you mean
node n, m;
n.next = &m;
but normally this would be done with dynamic allocation
node* n = new node;
n->next = new node;
because normally you would use node to create a variable length list. Since the length of the list varies there is no way to declare the right number of variables, instead you must allocate the nodes dynamcally.

New approach for adding a new Node to a Linked List

void addNewNode (struct node *head, int n)
{
struct node* temp = (struct node*) malloc(sizeof(struct node));
temp -> data = n;
temp -> link = head;
head = temp;
}
The code give above is the popularly wrong version of a function for adding a new node at the head of a linked list.
Generally the correct versions are like,
void addNewNode (struct node **head, int n);
void addNewNode (struct node * &head, int n);
I worked out another but simple function for the purpose which worked fine.
struct node* addNewNode (struct node *head, int n)
{
struct node* temp = (struct node*) malloc(sizeof(struct node));
temp -> data = n;
temp -> link = head;
return temp;
}
But I haven't seen this being used or discussed in code and tutorials and thus I am curious to know if this approach has some flaw.
The flaw is that you're relying on the caller to perform the last step of updating the head pointer to the list.
If the caller neglects to do this, the compiler will not complain, and for all intents and purposes the list will appear to not have changed (and you'll have leaked the memory for a node).
This is how linked lists work in most functional languages. For example, in ML you might do something like this:
val ls = [1, 2, 3, 4]
val newList = 0 :: ls
The :: syntax is actually a function which takes two parameters (0 and ls) and returns a new list which has 0 as the first element. Lists in ML are actually defined as list nodes, so :: is actually written very similarly to the addNewNode function you proposed.
In other words: congratulations, you have created an immutable linked list implementation in C! Understanding this is actually a fairly important first step to functional languages, so it's really a good thing to know.
Your approach is incompatible with the idea that addNode is a method on the list, more commonly used in OO languages.
Personally I think
list.add(element)
is a huge lot more intuitive than
list = add(list, element)
Dozens of "collections" libraries can't be wrong...
Afaik, that's the way how the lists in glib work and I'm sure the gtk folks weren't the first that use that way, so I wouldn't call it a new approach. I personally prefer to have a base structure, that holds the node count, first- and last-pointer.
This is not new. As pointed out by quinmars, glib has done it like this for over 10 years. It's a great idea, so congratulations for figuring it out.
One nitpick about your code, though: don't cast the return value of malloc() in C, and don't repeat the type name in the use of sizeof. Your allocation line should read like this:
struct node* temp = malloc(sizeof *temp);
See? Shorter, tighter, easier to read, harder to mess up. Better! :)
I see no problems in any of the mentioned correct code.
To change or not to change the head is a matter of design - and how to return modified list.
Good interface is implemented in std::list<> as an example where OOP is used, such approach is free of potential problems. head pointer is hidden and you can modify it as you want, and since caller do not store head explicitly, its reference to the list is always correct.
one things which looks ugly (when you use C++, not C) is a malloc, better to use 'new'.