-3

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

Miguel.G
  • 377
  • 1
  • 6
  • 20
  • 1
    What part don't you understand? This is one of the most common ways to use `malloc()`, it should be explained in any textbook or tutorial. – Barmar Oct 13 '18 at 15:04
  • What I don't understand is the general mean. A pointer to a struct called itemCopy is created but, what the assigment means? Okey, malloc allocate memory but what about (struct reportItem *)? – Miguel.G Oct 13 '18 at 15:07
  • Agreed; what specifically is the issue? You get a size. You allocate that much memory. You save the location of that memory to a pointer. – Dave Newton Oct 13 '18 at 15:07
  • The left part (before `=`) declares a variable of type `struct reportItem *`, i.e. a pointer to a `struct reportItem`. The right part allocates memory from the heap the size of a `struct reportItem` and assigns that to the variable just declared. The expression between braces, `(struct reportItem *)` is a _cast_ that tells the compiler that `malloc` returned a thing of type `struct reportItem`. The cast is not needed. – Paul Ogilvie Oct 13 '18 at 15:08
  • @Miguel.G That's a type cast, as any C programmer should know. – Barmar Oct 13 '18 at 15:09
  • Thanks @PaulOgilvie for your explanation!! "The cast is not needed" helped me a lot. – Miguel.G Oct 13 '18 at 15:16
  • @Barmar, I'm sure if I ask you something about advanced telecommunications you acts as me. Please, not all people is a C programmer, "as any normal person should know". :) – Miguel.G Oct 13 '18 at 15:18
  • SO is for programmers to help other programmers, it's not a programming school. You're expected to learn the basics, and this is really basic. – Barmar Oct 13 '18 at 15:26
  • SO: Founded in 2008, Stack Overflow is the largest, most trusted online community for developers to learn, share their knowledge, and build their careers. Developer: A developer is an individual that builds and create software and applications. There are many types of questions, depending skill level. Not all questions have to be "expert level" to be admissible. Have you forgotten your first questions? I'm sure you don't. Please, again, everybody wants to learn step by step. – Miguel.G Oct 13 '18 at 15:46

3 Answers3

2
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 
pmg
  • 106,608
  • 13
  • 126
  • 198
  • Thanks for your great explanation! I checked the first answer as the correct but with all of these answer everything is understood! Thanks again :) – Miguel.G Oct 13 '18 at 15:19
  • What error could the compiler catch if the cast would be absent? Can you give an example? – Paul Ogilvie Oct 13 '18 at 15:43
  • "_Using the type itself here may be regarded as an "accident waiting to happen"_" is correct. Can you elaborate and give an example so the OP understands? – Paul Ogilvie Oct 13 '18 at 15:44
  • Thanks @PaulOgilvie! I'll add some notes to my answer :) – pmg Oct 13 '18 at 15:47
1

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.

HackerBoss
  • 829
  • 7
  • 16
  • Hi! Thanks for your explanation! It is was I was looking for. With this explanation and "The cast is not needed" from Paul Ogilive everything is understood. Thanks again!! – Miguel.G Oct 13 '18 at 15:13
  • If this answered your question, please click the check mark to indicate it. – HackerBoss Oct 13 '18 at 15:15
1

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.

Gaurav Bahadur
  • 189
  • 2
  • 14