What is the difference between these two lines? - c

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.

Related

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*.

Creating a link in linked lists in C

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

C programming. Pointers to struct

This is my first post. I'm very confused with the C's pointer and its relation to struct. I've searched for more information but can't really conclude them. For example given this struct definition
typedef struct node
{
int info;
struct node *next;
}NODE;
Then what's the differences and effects of these four declarations;
1. NODE *node1 = malloc (sizeof(NODE));
2. NODE *node1 = (struct node *) malloc (sizeof(NODE));
3. NODE *node1 = (struct node *) malloc (sizeof(NODE *));
4. NODE *node1 = malloc (sizeof(NODE *));
Thanks in advance.
These are equivalent and allocate a block of memory the same size as a NODE struct.
1. NODE *node1 = malloc (sizeof(NODE));
2. NODE *node1 = (struct node *) malloc (sizeof(NODE));
These are just wrong
3. NODE *node1 = (struct node *) malloc (sizeof(NODE *));
4. NODE *node1 = malloc (sizeof(NODE *));
Line 3 allocates a memory block the size of a pointer to a NODE structure. The cast allows you to assign it without any errors being thrown, and possibly without warnings. But it's not what you want.
Line 4 does the same as line 3. malloc returns a void * which doesn't require casting, but a good static analyzer should give you a warning.
Either way, lines 3 & 4 are recipes for buffer overflows and undefined behavior.
Lines 3 and four would be correct if written thus:
NODE **ptr = malloc(sizeof(NODE *));
// node1 is a pointer to (heap) memory block of size NODE
1. NODE *node1 = malloc (sizeof(NODE));
// same as 1. (but 1. is the preferred way)
2. NODE *node1 = (struct node *) malloc (sizeof(NODE));
// (Wrong) node1 is a pointer to (heap) memory block of size pointer to NODE (a pointer to _usually_ 4 bytes)
// but you cast it to pointer to NODE (a pointer to more than 4 bytes)
3. NODE *node1 = (struct node *) malloc (sizeof(NODE *));
// (Wrong) same as 3
4. NODE *node1 = malloc (sizeof(NODE *));
Stick with number 1. as it's the common way to allocate an object in the heap (dynamic allocation): Object *object = malloc(sizeof(Object)). You can forget about 2. 3. 4. which complicate the issue and really not what you need.
Given:
NODE *node1 = malloc (sizeof(NODE));
NODE *node1 = (struct node *) malloc (sizeof(NODE));
NODE *node1 = (struct node *) malloc (sizeof(NODE *));
NODE *node1 = malloc (sizeof(NODE *));
ALL ARE BAD
3 and 4 are really bad
3) and 4) are not allocating enough memory for the struct, but only enough memory to hold the pointer to a struct (say 4 bytes on a 32-bit system) and then telling the compiler to treat that memory as if it was enough to occupy a NODE
1) is correct way to allocate enough memory for the structure (caveat other issues described below)
2) is bad practice because what you really mean is:
NODE *node1 = (NODE *) malloc(sizeof(NODE));
even though NODE is typedef struct node (2) says that you know that for sure.
Having said that,
All of them are bad practices for a reason explained later on below.
What you really want to do in practice is something like this:
Only use typedefs when you want to keep things really opaque about the inner structure (the way stdio does FILE) it's better practice to use struct foo bar; in your declaration than typedefing the struct. Especially when the structure is exposed to other parts of the program.
typedef is better used when you want to ensure that a type is uniformly interpreted on different architectures, e.g. the use of typedef unsigned long long uint64_t vs typedef unsigned uint64_t on 32-bit and 64-bit intel x86 cpus in stdint.h
A good example
struct node {
struct node *next;
size_t n_dlen;
void * n_data;
};
int main() {
struct node *node;
node = malloc(sizeof(*node));
}
Notice that I used sizeof(*node) instead of sizeof(struct node), because if I decide later on that node should be some other type say struct new_node * then all i have to do is change the declaration and the sizeof(*node) will still be okay.

Assign variable to struct member

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.

Malloc syntax in C

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.

Resources