In the books I read that the syntax for malloc is malloc(sizeof(int)) but in one of doubly linked list program I see the following:
newnode=(struct node *)malloc(sizeof(struct node))
What is (struct node*) doing here? What is this entire code doing? btw, the code for the struct in the program is as below.
struct node
{
char line[80];
struct node *next,*prev;
};
struct node *start=NULL,*temp,*temp1,*temp2,*newnode;
Thank you
The code is dynamically creating a pointer to a single type of struct node. In most versions of C, the (struct node *) cast is not needed, and some argue that it shouldn't be used. If you remove the cast, it will be a void*, which can be used for any type.
Therefore:
newnode = (struct node*)malloc(sizeof(struct node));
is roughly equivalent to:
newnode = malloc(sizeof(struct node));
See: Specifically, what's dangerous about casting the result of malloc?
Note 1: If you are using Visual Studio to write your C code, it will give you red underlining if you don't cast the result of malloc. However, the code will still compile.
Note 2: Using malloc in C++ code requires you to cast the result as shown in your example.
You ran into a very bad code. C programmers never cast a result of malloc(). Not only it is not needed but can be harmful.
You should pass the number of bytes that you want malloc to allocate as argument. That is why in this code sample you use sizeof(struct node) telling C to allocate the number of bytes needed for a struct node variable. Casting the result like is shown in this code is bad idea by the way.
malloc returns a void pointer .
(struct node*) does a explicit conversion from void pointer to the target pointer type
"malloc" returns a void-pointer. (struct node *) is type-casting the result of malloc to a "node struct pointer", which is (undoubtibly) what "newnode" is.
Related
Why is there a need for * (in front of insertAtfirst)? I know that we use it for creating pointers and for dereferencing but I am unable to comprehend its logic over here.
struct Node *insertAtFirst(struct Node *head, int data)
{
struct Node *ptr = (struct Node *)malloc(sizeof(struct Node));
ptr->next = head;
ptr->data = data;
return ptr;
};
Even though this particular bit of code will compile in C++, it is clearly only suited to C programming.
The star is part of the return type, not the function name.
struct Node * reads as "pointer to a Node"
struct Node * f(...) reads as "f is a function returning a pointer to a Node"
Maybe using typedef will make it clearer?
typedef struct Node * NodePtr; // NodePtr becomes an alias to "struct Node *"
struct Node {
NodePtr next;
int data;
};
NodePtr insertAtFirst(NodePtr head, int data)
{
NodePtr ptr = (NodePtr)malloc(sizeof(struct Node));
ptr->next = head;
ptr->data = data;
return ptr;
}
I can only advise you to get familiar with typedef, it's a great way to make C/C++ code more readable and safe, especially when dealing with these pesky arrays and pointers.
Most languages will (wisely) hide pointers from the programmer in properly managed references. C/C++ are archaic languages that allow the programmer to deal with raw memory, which is a bloody dangerous business, as you will soon find out.
Using such a code in C++ is technically possible, but that would be a terrible idea. C++ offers much safer ways of handling linked lists.
Alas, C does not. So, if you're actually learning C, as your example suggests, you'll have no choice but to learn to cope with pointers. Good luck :)
The * is part of the return type of the insertAtFirst function.
It tells the compiler what it should expect as result of this function.
It is not related to the function name itself.
So the code is telling the compiler insertAtFirst will return pointer to Node (Node*).
Inside the function ptr is declared as Node*.
Finally the function return ptr.
Because the function returns a struct Node pointer (struct Node*).
The placement of the pointer symbol is sometimes confusing, so I recommend to put it directly after the type name. e.g. char*
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*.
Here is the code to create a link in the list which i read off the internet to try understand linked lists in c:
//insert link at first location
void insertFirst(int key, int data) {
//create a link
struct node *link = (struct node*) malloc(sizeof(struct node));
link->key = key;
link->data = data;
//point it to old first node
link->next = head;
//point first to new first node
head = link;
}
I am really not understanding how the following line works as a whole:
struct node *link = (struct node*) malloc(sizeof(struct node));
and more specifically:
(struct node*)
because my understanding is that the asterisk must come before the pointer name and yet its at the end of the struct name. Please correct me if I'm wrong and please if you can, explain how this works?
Casting the return value of malloc is unnecessary.
As per standard 7.22.3.4
The malloc function returns either a null pointer or a pointer to the
allocated space.
You should check its return value to know whether it succeeded or not.
What malloc does?
The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate.
my understanding is that the asterisk must come before the pointer name and yet its at the end of the struct name
Here you are not dereferencing anything. Rather you are typecasting. (which is again I would repeat that unnecessary).
struct node* here is a type of the pointer variable. Same way int or double is a type, this is also a type.
Assume you have to create database of a students having some entities.
struct node
{
int id;
char name [100];
};
Next thing,
struct node *link = (struct node*) malloc(sizeof(struct node));
How above line works ? you need to create one node or memory, So how will you create it, use malloc(). Next things how much memory you are going to create , equal to total size of your data members of structure, so for that its using
struct node *link = malloc(sizeof(struct node));
here link is nothing but name of dynamic memory we created to put some data into that. once memory is created put some data into memory.
scanf("%d %s\n",&link->id,link->name);
similarly you can do above task no of times.
typecasting is not compulsory or not advised to do. So below statement is correct.
struct node *link = malloc(sizeof(struct node));
In order to create a linked list you have to allocate the units -in your case :
struct node
so either you pre-allocate the memory for the list or dynamically allocate them every time you add a node to the list, the memoery for the node has to be recruited from somewhere, in this case - malloc does that.
Hope that helps
struct node *tempNode = (struct node*) malloc(sizeof(struct node));
//and
struct node *tempNode = malloc(sizeof(struct node));
struct node *tempNode = (struct node*) malloc(sizeof(struct node));
you're dynamically allocating space to a node pointer tempNode and typecasting it to be a struct node* type. (pointer to structure)
struct node *tempNode = malloc(sizeof(struct node));
The same as above, except without the explicit typecast (struct node*)
There is no difference. Since malloc returns type void *, it can be assigned to a variable of any pointer type without casting. As John Bode mentioned, casting the result of malloc is considered bad practice because it may mask the compiler error that would result from having some other definition of malloc.
Since you are casting it correctly there's no difference between the two.
But the cast is generally frowned upon in C since a void* can be implicitly converted into any other (data) pointer type.
Also see this C FAQ entry: What's wrong with casting malloc's return value?
A third one is there:
struct node *tempNode = malloc(sizeof *tempNode);
which is better since it makes for less changes in case the type is changed.
With the call to malloc, memory is allocated that has the size of the struct node in bytes. It returns a void* to the allocated memory.
Now the thing is: both of your lines do exactly the same, but the second line will lead to a warning when compiled with a C++ compiler.
C allows implicit conversion of a void* to a different pointer type, whereas the C++ compiler will - at least - warn you, or give you an error.
I have created a struct with a char variable in it. I want to assign a string value to it when using it inside of a method and then print it. I have been looking around but can't find a valid answer, but can't find what I'm doing wrong. Why am I getting the error below?
Here is what I have tried:
struct node{
char *val;
struct node *first;
struct node *last;
};
void main(){
struct node *new_node;
new_node =(struct node *)malloc(sizeof(struct node));
new_node.val = "a";
printf("%s",new_node.val);
}
I get the error:
request for member 'val' in something not a structure or union
new_node should be accessed as a pointer and not an instance.
try new_node->val instead of new_node.val
response to edited question
As you have changed from char val to char *val you will need additional processing:
allocate memory for *val : new_node->val=(char*)malloc(sizeof(char))
assignment will need to dereference the pointer : *(new_node->val)="a"
Print statement should also dereference the pointer : printf("%c",*(new_node->val))
you should free the val pointer before freeing new_node: free(new_node->val)
new_node.val should be replaced with new_node->val. since new_node is a pointer. Keep in mind that new_node->val (often refereed as the arrow operator) is the shorthand for (*new_node).val.
Also i believe you can write:
node *new_node = malloc(sizeof(node));
For easier reading and cleaner code since malloc will just return a pointer to a given memory address. Use -Wall or other warning flags when you compilate your program to experience less logical errors or seg faults.