I am approaching to use this code for building singly linked list. I am pointing out the lines which get me bit confused .
struct node
{
int data;
struct node *next;
}*start=NULL; // point 1
void creat()
{
char ch;
do
{
struct node *new_node,*current;
new_node=(struct node *)malloc(sizeof(struct node));
printf("\nEnter the data : ");
scanf("%d",&new_node->data); //point 2
new_node->next=NULL; // point 3
if(start==NULL)
{
start=new_node;
current=new_node;
}
else
{
current->next=new_node;
current=new_node;
}
printf("\nDo you want to creat another : ");
ch=getche();
}while(ch!='n');
}
point1: What is the advantage declaring the structure node as a pointer?
point2: scanf("%d",&new_node->data);
Not getting the idea how the data is stored here to the 'data' field in context of pointer and structure?
How Linked lists are different from arrays? Consider the following points :
An array is a static data structure. This means the length of array cannot be altered at run time. While, a linked list is a dynamic data structure.
In an array, all the elements are kept at consecutive memory locations while in a linked list the elements (or nodes) may be kept at any location but still connected to each other.
So considering the purpose of dynamic creation of linked list we do not know how many nodes user will create.
Therefore in this case to allocate memory dynamically, pointers are used.
Using pointers will give you the memory location
for your struct.
The purpose of scanf() is to accept the data and store it into the memory location. Here you are accepting an interger value for your data into struct which is named as new_node. So assume your new_node is something like:
new_node = {int data | struct node *next} Here you want to accept the value for your integer field data
There for the scanf will store what ever value you will type into the address location of new_node's data.
Here "1" represents your new_node->data accepted and "NULL" is
new_node->next the pointer to next node.
0a) pointers only save memory addresses, the compiler relies on your declaration to determine how much memory from that address (from *ptr to *ptr + size) is considered part of the object.
0b) within the struct node, you are saving the address of the 'next' node instead of saving the values of the 'next' node. this means at any time there's only one copy of each node.
1) }*start=NULL; is a short-hand way of declaring a struct node pointer called start with initialized value NULL, which means its pointing at nothing.
2a) Declaring pointers of type struct node lets the compiler know that after the pointer it can expect sizeof(struct node) amount of memory behind it to be readable. Obviously you have to malloc that memory beforehand otherwise errors will occur. Finally, the "ptr->data" is equivalent to "(*ptr).data", which dereferences the pointer and then asks for the data element of the struct node.
2b) the form of
int x;
scanf("%d",&x);
passes the &x(address of x) to the function, which reads an int and puts it AT address pointed to by &x. so &ptr->data is basically == address of data.
point1: What is the advantage declaring the structure node as a pointer?
You can use pointer to structure as function argument rather than structure itself so as to avoid making copy of struct. As when you pass a struct compiler makes a copy of that struct.
point2: scanf("%d",&new_node->data);
Arrow Operator(->) is used to access members of structures by pointer variable.
Here in above scanf statement new_node is the pointer variable which is accessing member data of the structure.
This operation is similar to the Dot Operator(.) where we access members of structure using ordinary structure variable.
Related
Im new to community this is my first post so hello to everyone.
I have recently started studying the coding and c language in specific.But i have a confusion when it comes to structures and how they are referenced in memory.
This is example when my lack of understanding makes me unable to understand what exactly happening in code.
For example when asking malloc for space for lets say a node structure the way i understood it until now is that computer will allocate memory of size of struct if instructed by size of operator in parenthesis. Therefore that many memory locations will be allocated starting at specific location pointer points to.But when we use pointer of struct type we allocated memory for (in this case struct node) it just stores a address of first byte of said struct as all pointers do if i understand correctly.
Then when
`*(pointername).exactfieldname
For example if we assume there is node structure defined in code.With two fields for int called numbers and for pointer called next.
node *n=malloc (sizeof(node));
*(n).next=malloc (sizeof(node));
syntax is used i cant understand how it works exactly.How is a computer just through pointer to a first byte out of certain number of bytes that were allocated suddenly able to access fields of structure?
Reason this is additionally confusing is because when defining a node struct for linked list for example it is possible to define pointer to struct of struct type being defined before it is defined because its just a pointer so it only stores address. Due to that fact struct pointer cant have any special property allowing it to access fields its still just a pointer right?
When pointer is derefrenced does it mean that computer goes to pointed location and enters a strucutres. And then rest of syntax after dereferencing pointer like *(pointer ).fieldname can be used because now computer is inside structure and interacts with it and .fieldname refers to that instruction now?
I'll try to answer despite your question lacking some clarity.
If I get you right, you are confused by this:
typedef struct node {
struct node *next; // <<<< here
some_type_t data;
} node;
In the line marked, the compiler does not yet know what struct node looks like.
That is correct. It doesn't need to know that because we only store a pointer.
In that place you cannot define a non-pointer element of that type (or any other incomplete type) for exactly that reason.
Now if you come to that part:
node *n=malloc (sizeof(node));
n->next=malloc (sizeof(node));
(Note: Your syntax was incorrect)
You seem to wonder how the compiler would know what n->next really is as it was unknown when the struct was defined.
That does not matter.
It is known when the compiler comes to this line. You can only dereference a pointer if the type is fully known in that location.
The compiler now knows what node* means and can address the fields in *n and in the same way it can deal with n->next.
Study and try do understand the following code.
Compare the values that are printed out. %p will print address values (hex format) and %d prints decimal values.
Take a good look at the parameters that are passed to the printf function. & is the 'address of' operator and -> is a dereference operator, which is equal to *(pointer)..
struct node {
struct node *next; //pointer to struct node
struct data_rec { //embedded struct
int value; //some value of type int
} data; //data of type struct data_rec
};
//allocation on the heap -> pointer to struct node
struct node *allocated_node = malloc(sizeof(struct node));
allocated_node->next = NULL;
allocated_node->data.value = 0;
//allocation on the stack (sizeof(struct node) bytes)
struct node base_node;
base_node.next = allocated_node;
base_node.data.value = 42;
//prints some information of the node
void printNodeInfo(struct node *node_)
{
printf(
"address of node: %p\n"
"address of node.next: %p\n"
"value of node.next: %p\n"
"address of node.data: %p\n"
"address of node.data.value: %p\n"
"value of node.data.value: %d\n",
node_,
&node_->next,
node_->next,
&node_->data,
&node_->data.value,
node_->data.value
);
}
int main()
{
printNodeInfo(&base_node);
printNodeInfo(allocated_node);
return 0;
}
I created a structure for a linked list node in C as follows.
struct node
{
int data;
struct node *next;
} *START = NULL;
Then when I need to access the properties of the structure, I create a pointer to structure as follows.
struct node *node1;
node1 -> data = 12;
node1 -> next = NULL;
I want to know if we can use
struct node node1
instead of the current declaration and what changes would that make in the program.
Also, I want to know why *START=NULL is outside the structure and what its data type is ?
You need to allocate the memory for the struct. Here you have a simple function which appends the node to the end of the list
struct node
{
int data;
struct node *next;
} *START = NULL;
struct node *append(int data)
{
struct node *node1 = malloc(sizeof(*node1));
struct node *list = START;
if(node1)
{
node1 -> data = data;
node1 -> next = NULL;
if(list)
{
while(list -> next)
{
list = list -> next;
}
list -> next = node1;
}
else
{
START = node1;
}
}
return node1;
}
START is the variable of type pointer to the struct node.
struct node *node1;
node1 -> data = 12;
node1 -> next = NULL;
First, the above code doesn't initialize node1 to a valid memory address. It merely creates a pointer called node1 which can take the address of a variable of struct node type which hasn't been properly initialized.
You need to change the code to the following.
struct node *node1 = (struct node*)malloc(sizeof(struct node));
node1 -> data = 12;
node1 -> next = NULL;
The above will allocate memory for struct node type and initialize node1 with the address of the allocated memory.
Now let's get to your questions.
I want to know if we can use
struct node node1
instead of the current declaration and what changes would that make in the program.
You can use the above declaration in your program, but it will create node1 on stack rather than on heap. Probably this is not the behaviour you want since the variable made on stack has the lifetime of the scope in which it's created. In your case I assume you want to create a linked list (or similar structure), therefore you need the list to be accessible even after the function in which the appending happens returns.
Anyway, if you created the variable on stack you can simply use . operator to access structure members.
struct node node1;
node1.data = 12;
node1.next = NULL;
Also, I want to know why *START=NULL is outside the structure and what
its data type is?
It simply defines a pointer variable named START that can point to struct node and initialize it with NULL.
[...] when I need to access the properties of the structure, I create
a pointer to structure as follows.
struct node *node1;
node1 -> data = 12;
node1 -> next = NULL;
Not exactly. You have declared node1 as a variable of type struct node *, but you have not created a pointer, in the sense that you have not given that variable a value that points to any structure. Subsequently attempting to access a struct node via that variable's (indeterminate) value therefore produces undefined behavior. Among the more likely outcomes are that your program crashes or that unexpected changes are made to random objects in its memory.
To be able to use node1 to access a struct node as you show, you first need to assign it to point to one (or at least to memory that can be made to contain one). You can do that either by assigning it the address of an existing struct node or by allocating memory sufficient for a struct node and assigning its address to node1. More on those alternatives later.
I want to know if we can use
struct node node1
instead of the current declaration and what changes would that make in
the program.
You definitely can declare node1 as a struct node instead of as a pointer to one. In the scope of such a declaration, you would access its members via the direct member-access operator (.) instead of via the indirect one (->):
node1.data = 12;
node1.next = NULL;
Furthermore, one of the ways to obtain a pointer to a struct node would be to use the address-of operator (&) to obtain that structure's address:
struct node *node_ptr = &node1;
HOWEVER, the lifetime of the node1 object declared that way ends when control passes out of the innermost block in which the declaration appears (if any), any pointers to it notwithstanding. As such, that usually is not what you want for a linked-list node.
For linked-list applications (among others), one generally wants an object whose lifetime doesn't end until you say it should do, and that can be achieved by dynamically allocating memory for the structure. For example,
struct node *node_ptr = malloc(sizeof(*node_ptr));
The allocated memory remains allocated until you explicitly free() it, whether in that scope or in another. Either way, to access the structure members through a valid pointer, one uses the indirect access operator, as in your example:
node_ptr->data = 42;
node_ptr->next = NULL;
or, equivalently, one first dereferences the pointer and then uses the direct member access operator:
(*node_ptr).data = 42;
(*node_ptr).next = NULL;
.
Also, I want to know why *START=NULL is outside the structure and what
its data type is ?
You said that you wrote the code. If you don't know the significance of the *START=NULL part, then what is it doing in your code?
In any event, it is analogous to the *node_ptr = &node1 above. START is declared (at file scope) as a pointer to a struct node, and its initial (pointer) value is assigned to be NULL, which explicitly and testably does not point to any structure.
When do we use structure variable and structure pointer?
Depends on the use case. When you create a structure variable you actually allocate the structure object on the stack. When you use pointer you usally allocate the structure object in heap memory and point to this object via the pointer.
You can resize and deallocate the dynamically allocated structure object whenever you want to, while the static can't be changes in size and it is only destroyed once the scope of it ends (in case of an automatic structure variable).
More details to the difference between static vs. dynamic allocation you can find in the links below the answer.
Which way you choose, depends on what you want to do and how you want to do it.
I want to know if we can use struct node node1 instead of the current declaration and what changes would that make in the program.
That would make node1 a variable of the structure itself; it would not be a pointer to an object of the structure only anymore.
Beside the things mentioned above and others, the access to the members would be different:
node1 . data = 12;
node1 . next = NULL;
Also I want to know why *START=NULL is outside the structure and what it's data type is.
START is of type struct node * (a pointer to struct node) and initialized to NULL. It's definition is outside because it isn't a member, it is a pointer to an object of the structure.
Note that you need to assign a pointer to struct node to point to an object of struct node, but that is not what you did at:
struct node *node1;
node1 -> data = 12;
node1 -> next = NULL;
So, this would invoke undefined behavior.
Allocate memory for the structure:
struct node *node1 = calloc (1, sizeof(*node1));
if (!node1)
{
fputs("Failure at memory allocation for node1!", stderr);
return EXIT_FAILURE;
}
node1 -> data = 12;
node1 -> next = NULL;
Related regarding point 1.:
What and where are the stack and heap?
Stack variables vs. Heap variables
Why would you ever want to allocate memory on the heap rather than the stack?
Which is faster: Stack allocation or Heap allocation
Feel free to edit the title if it doesn't make sense. So I've been using malloc for a while without really being completely sure of how it works. If I create an int pointer and set it equal to malloc(10*sizeof(int), I figure that it allocates a block in memory of 10 times the size of one int, then returns the starting address of this allocation, but nothing is actually initialized within that memory yet. Am I OK so far?
Now say I create a struct for linked list nodes like this:
typedef struct node_ {
int data;
struct node_ *next;
} Node;
and then have a create linked list function:
Node* LLCreate(int data) {
Node *head = malloc(sizeof(Node));
if ( head != NULL) {
head->next = NULL; // don't get how malloc created `next`
head->data = data; // or `data`
}
return head;
}
What I don't get, and can't seem to google appropriately, is, if head is just the starting location in memory of an empty block of size Node, and not an actual variable, how does it have the local variables of next and data?
Maybe this is a nonsensical question because I have some fundamental misunderstanding of what's going on here, but if anyone understands what I'm trying to ask and could clear this up for me I'd really appreciate it.
It doesnt have local variables like next and data.
next and data are just used to calculate the address relative to from where node is pointing.
When you do node->data then the address is calculated as address pointed by node + (total bytes required by any metadata for malloc) + 0 because data is the first member of node struct.
And when you do node->next then the address is calculated as address pointed by node + (total bytes required by any metadata for malloc) + sizeof(data) , because next is the second member of the node struct that comes after data member.
In linked list I came across the following structures
struct node
{
int data;
struct node *next;
};
struct node *list;
What is the difference between list and next?
They are both pointers to the struct node.
But the difference is that next is a member of the struct while list is an object.
That means that you can use list as
list->data;
But to use next, you need to use
list->next->data;
or
struct node a;
a.next->data;
That is, it behaves like needs an object just like any other members of the struct.
You can refer this code
> There is no difference between these Two Pointers both are refrences
and store the adress of the object.
but the *next behaves as the variable of the struct and the other pointer behaves as an object of the Struct.
1st of all in the snippet shown there only "exists" one pointer, that is list.
However:
list is an instance of a pointer pointing to struct node. It uses memory.
next is a member of, part of the definition of the type struct node and of type pointer to struct node. next is no instance of a pointer. It does not use memory.
The Both pointers list and next are pointing to node structure.
The Main Difference is:
list is not part of the structure node, where as next is part of the structure node.
I'm still having trouble understanding how to copy structs that include char* fields\other struct fields:
typedef struct node{
int id;
struct node* parent
char * nodeName;
struct node* nodes[100];
}NODE,*pNODE;
I want to use this function : pNODE copyNode(pNODE oldNode)
1. i know that first I should do allocation for the new pointer data , and do the followong:
pNODE newNode = (pNODE)calloc(1,sizeof(NODE));
newNode.id=oldNode.id
//for the string that I want to copy I should allocate and use strcpy - in order not to point at the same string
but now I'm lost regarding the parent node, how do I copy it ? if I just do : newNode.parent=oldNode.parent
I point at the same parent object, and if I change it's Id for example - it will change both the id of newNode and oldNode. how can I copy it?? without pointing at the same one?
and how can i copy the pointer array??
thank you!
Take a look at the memcopy function:
memcpy(oldNode.parent, newNode.parent, sizeof(node)).
Of course, you first need to allocate memory for the newNode's parent, using malloc (calloc doesn't make sense in this context - it's used for arrays)
newNode.parent = (NODE*)malloc(sizeof(NODE))
If you want to do a deep-copy (i.e. don't reuse referenced objects), you should go through the newNode struct and allocate memory for each pointer contained in the struct and then apply memcopy.