I don't know what the next assigment means:
struct reportItem * itemCopy = (struct reportItem *) malloc(sizeof(struct reportItem))
Could someone explain me the assigment step by step? I really don't know what does it means.
Thanks
I don't know what the next assigment means:
struct reportItem * itemCopy = (struct reportItem *) malloc(sizeof(struct reportItem))
Could someone explain me the assigment step by step? I really don't know what does it means.
Thanks
struct reportItem *itemCopy = (struct reportItem *) malloc(sizeof(struct reportItem));
// ^^^^^^^^^^^^^^^^^^^^^
The cast is unnecessary and may hide an error the compiler would have caught in its absence (1)
struct reportItem *itemCopy = malloc(sizeof(struct reportItem));
// ^^^^^^^^^^^^^^^^^^^
Using the type itself here may be regarded as an "accident waiting to happen" (2). It is safer to use the object itself
struct reportItem *itemCopy = malloc(sizeof *itemCopy);
So now it's a good looking statement :)
This calls the library function malloc()
(which attempts to reserve an area of memory for the program to use) and assigns the resulting value to itemCopy
.
It's the programmer responsability to check if malloc()
managed to reserve the memory before using that memory.
if (itemCopy == NULL) {
//malloc failed to reserve memory
fprintf(stderr, "no memory.\n");
exit(EXIT_FAILURE);
}
Also the programmer is responsible to release the memory (back to the OS) once that memory is no longer required.
//use itemCopy
free(itemCopy);
(1) cast hides error
If there is no prototype in scope for malloc()
the compiler assumes it returns an int
. Then, with the cast is silently converts that illegal int
(illegal because it is, in fact, a void*
value) to a pointer. The error is the absence of the #include <stdio.h>
and the cast. If you simply remove the cast, the compiler complains about the conversion from int
to pointer. If you #include <stdio.h>
and keep the cast it is redundant (and redundant is bad).
(2) using the type for determining amount of memory to allocate is an "accident waiting to happen"
The call malloc(sizeof(struct whatever))
is an "accident waiting to happen" because it forces the programmer to change code in more than one place with a single structure change.
Let's imagine there's a struct Car
with some properties... Later on it's decided to change part of the code to the new revamped struct Vehicle
(while keeping the struct Car
active). Using the type name in the malloc()
call forces 2 changes
struct Vehicle *x = malloc(sizeof (struct Vehicle));
// ^^^^^^^^^^^^^^^^ prevented accident
while using the object requires just one change
struct Vehicle *x = malloc(sizeof *x);
// ^^ *x is of the correct type
struct reportItem
is a structure type that was previously declared. A structure in C basically is a block of data that can be read in parts, where each part has a type and a name. The first part declares a pointer itemCopy
, which is just a variable storing a memory address. The struct reportItem
just tells the compiler that the data at that memory address should be interpreted as a reportItem
structure. malloc
is a function that allocates memory to store things. You tell it how many bytes of memory you need, and it returns a pointer holding the address of the first byte of that newly allocated memory. sizeof
returns the size, in bytes, of an object or type of object. In this case, it allocates enough memory to store one reportItem
structure. The pointer returned from malloc
is then casted to the declared pointer type, and itemCopy
is assigned to hold that address.
sizeof(struct reportItem) returns the size taken by the data type struct reportItem
malloc allocates the requested bytes in this case whatever is returned by sizeof(struct reportItem)
(struct reportItem *) is used to type cast the value returned by malloc. However it is not required, you can check this for more, do i need to cast malloc?
struct reportItem* ItemCopy is then assigned the base address of the casted fixed memory of the size taken by reportItem.