structure and linked list - c

struct node
{
int info;
struct node *link;
}*start;
void main()
{
struct node*tmp,*q;
tmp=(struct node*)malloc sizeof(struct node);
}
now my first question is when we declare structure is any struct type node is created in memory?
second question is ,if yes then here i take a start pointer which is pointing to struct type node so without specifying the address of struct node to start pointer how start pointer pointing the struct type node which is created during declaration plz clear me this how internally this is happening i have lot of confusion on that
third question is initially tmp and q pointer variable all are pointing towards the same struct node
plz expalin the concept malloc and calloc how internally they create node
thx for helping me out

You can declare a structure type without declaring any variables. However, your code defines a pointer variable, start.
The variable start is initialized to 0, so it is not pointing to anything.
The variables tmp and q are not initialized at all and cannot be safely used until assigned a value. You initialize tmp in the next line; q is still uninitialized.
malloc() provides space for the pointer to point to; it does not initialize that space. The value in tmp->info is indeterminate; the value in tmp->link is indeterminate too. If you had used calloc(), then tmp->info would be zero and tmp->link would be null (on all practical systems — theoretically, there could be a system where tmp->link was not properly initialized).
Finally, note that void main() is bad. The C standard says that the return type of main() should be int. Further, unless you've got a C99 or later compiler, you should include return(0); or equivalent as the last line in main() — or a call to exit().

Related

When pointer points to structure location in memory how can we access structures fields just through that address?

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;
}

C Struct Initialization

#include <stdio.h>
struct node {
int data;
struct node* next;
};
typedef struct node Node;
int main() {
Node a;
a.data = 1;
if (!a.next) {
printf("hello world");
}
}
I'm writing a little linked list program to start learning c, and I'm confused as to why a.next is not null.
In short, whenever you allocate some memory in C (either explicitly or implicitly), the memory is initialized with whatever was there when the stack frame for your main function was created (ie. garbage). This is true of your int value as well (remove the a.data = 1 and print the value of a.data). C doesn't zero the memory it allocates for you (which makes C more efficient). As Anandha suggested, just set the pointer to NULL to avoid this problem.
You should initialize the pointer with NULL, the declared pointer may contain garbage value pointing to anywhere in the memory.
So a.next=NULL

What does the following code do in regards to structure pointers?

struct node *link = (struct node*) malloc(sizeof(struct node));
The above code is part of a larger program that creates a linked list. I already have and understand the code that leads up to this which creates the structure "node". I just am unsure what the code I provided does in regards to that structure.
The above code simply allocates memory of dimension "struct node", then cast it to the same type and assign the returned pointer to a variable called link.
Well, let's go through it piece by piece....
First, this tells that you are after a pointer to a struct of type node not a struct node but a pointer that points to a memory location holding a struct node
struct node *link = ...
then, let's have a look at the signature of the malloc() function.
void *malloc(size_t size);
It tells us that the return type is void *, which , in C, can be casted to any other type and generally used to provide a universal interface to the caller (similar to but not same as templates in C++ or other languages).
With the below cast, we are casting void *, the return type of malloc() to a pointer to a struct of type node, i.e. struct node*
(struct node*) malloc(...);
Looking at the argument passed to the malloc() function, which gives the size of an expression measured in char-sized storage units (sizeof(char) is guaranteed to be 1)
...sizeof(struct node)...
you are asking your compiler to return you the size of your struct node (this, of course, depends on the members of your struct).
Putting it all together...
struct node *link = (struct node*) malloc(sizeof(struct node));
allocate memory as big as a struct of type node can fit and return me a pointer to the start of this memory chunk. At the same time, mark this chunk of memory so that you (the compiler) will know that this area is reserved for a struct of type node
Edit : In C, you do not need to cast the type of the pointer returned by malloc() to another pointer type. In your case, the returned void * pointer from malloc() is automatically promoted to the appropriate pointer type, i.e. struct node*.

insertion in linked list -

I was reading Skeina's book. I could not understand this code. Basically what is the use of double pointer. And what is the use of *l = p? Can anyone please explain by diagram.
void insert_list(list **l, item_type x) {
list *p; /* temporary pointer */
p = malloc(sizeof(list));
p->item = x;
p->next = *l;
*l = p;
}
You shouldn't call it a "double pointer" because that would be a pointer to a double. It is a pointer to a pointer, and it is used to allow the function to alter the value of an argument which happens to be a pointer. If you're familiar with C#, it's like an out argument. In this situation the l argument used to get both IN and OUT behavior, but you may often see this used for output only.
Since this function returns type void it very well could have been written without the use of the pointer to a pointer like this:
list * insert_list(list *l, item_type x) {
{
list *p; /* temporary pointer */
p = malloc(sizeof(list));
p->item = x;
p->next = l; // note that this is not *l here
return p;
}
This change would require the code that calls the function to update it's own handle to the list since the head of the list is what's being changed.
This function performs a very simple task: it inserts a list node at
the position for which it receives a pointer. There is nothing
special about double pointers, they are just pointers to pointers. They hold the address of a pointer, which contains the address of an object.
void **l contains the address of a list * pointer. *l retrieves
this address and *l = p stores it.
malloc is used to allocate a
list structure, p receives the address of the allocated structure.
The code is somewhat sloppy as p is not checked for NULL before
dereferencing it. If malloc fails because of lack of memory, the
program will invoke undefined behaviour, hopefully stopping with a
segmentation fault or something potentially worse.
The node is initialized, its next pointer is set to the node pointed
to by the l argument, and finally the new node's address is stored
at the address passed as the l argument. The effect is simple: the node is inserted at *l.
This method is clever ad it allows the same function to insert a new node anywhere is a list. For example:
list *head = NULL;
...
/* Insert a LIST_A node at the beginning of the list */
insert_list(&head, LIST_A);
...
/* insert a LIST_B element as the second node in the list */
insert_list(&head->next, LIST_B);
...
/* find the end of the list */
list *node;
for (node = head; node->next; node = node->next)
continue;
/* insert a LIST_Z node at the end of the list */
insert_list(&node->next, LIST_Z);
The only tricky thing above is the concept of pointer itself, here is a simple overview:
Memory can be conceptualized as a (large) array of bytes, addresses are offsets in this array.
char variables by definition are single bytes,
int variables occupies a number of bytes specific to the architecture of the system, typically 4 or 8 bytes in current hardware.
Think of pointers as variables holding the address in memory of another variable. They need to be large enough to hold any valid address in the system, in current systems with more than 4 GB of physical and addressable memory, they are 64 bit long and occupy 8 bytes.
There is a special address value NULL which represents no object and is used to specify that a given pointer does not point to any real object. The address 0 is used for this purpose. malloc will return NULL if it cannot allocate the memory requested, the return value should be tested, as storing a value at this address is forbidden and usually caught as an invalid access (segmentation fault).
This summary is purposely simplistic. I used the term variable instead of object to avoid the confusion with OOP concepts.

Does the struct get freed this way in C?

I have the following struct which I use to implement a priority queue
struct q_element
{
//Declaration of struct members
int element;
int priority;
struct q_element *next_element;
};
and I use a pointer to a struct 'cur' to start from the first item in the queue
struct q_element* cur = start_element;
and keep moving until I find the one I want to delete from list.
while (cur->priority!=max_priority)
cur = cur->next_element;
Does the following line of code actually free the struct? Because 'cur' is a pointer to the struct I wasn't completely sure.
free(cur);
You need to pass a pointer to free, so free(cur) is the way to go, assuming that the struct itself has been allocated using malloc/calloc/realloc. Specifically, if you allocated your curr in the automatic memory (i.e. on the stack) you are not supposed to call free on it.
It looks like q_element is part of a linked list. Freeing the struct itself will not free other structs pointed to by it, so if you'd like to free the struct along with its tail, you need to write a loop.
Finally, when you free memory pointed to by some pointer in your program, it is a very good idea to assign NULL to the pointer that you freed to avoid accidental double-freeing and undefined behavior on accessing freed memory.

Resources