Let's start with the basics:
malloc(size_t) : It is a function of the standard C library used to "request" memory from the computer dynamically , that is, you can use store more data in your program when you use it correctly.
Going back to your code:
Both work because you do not have enough warning flags activated. : P
int * , which is different from
int and what you do with:
Is to let the
printf function know that you are passing an integer, which in theory is true, but you are invoking the devil , I say, indefinite behavior when doing this, since not all platforms define
printf in the same way.
You are passing to
printf the correct value, which tells us that the correct way to assign a value value to a pointer is using the operator
* before the name of the variable :
*pi = 5;
Depending on the level of the pointer and its function.
pi = 5;
Some compilers will complain, others will not, but it is understandable, since when doing that above you tell the compiler:
Make the pointer
pi point to memory address
Which will be good and valid (For some compilers, for others not) , but when doing:
pi = 5;
We call the devil and BÚM! Segmentation Fault, this is because the memory address 5 'is not valid within the memory assigned to your program.
Last point, when you do:
char *cadena = malloc(5 * sizeof(char));
cadena = "hola";
You are stealing memory (which becomes impossible to recover unless there is another pointer with the same address) , because the assignment of strings in C does not work like this, for this you must use some of the functions given by the C library or create your own function that copies the characters from the beginning to the length of the string:
char *cadena = malloc(5); // Es lo mismo.
sprintf(cadena, "%s", "hola");
With the above or using the function
strcpy you will have the result you expect.
Note: Strings in C, or are arrays of characters or are pointers to character, so if you do:
*cadena = "hola"; you are not assigning the value to a pointer to character, but to a character as such and the compiler if you are going to warn about misuse of literals.
A final point that must be clarified is that at the end of the life cycle of each pointer whose address comes from one of the functions to place memory, you should always call
free passing said variable as an argument, to save that memory asked earlier.
Regarding your question "Is the code correct?":
The code is correct for syntax, but the logic does not go with the C style; C is a language closer to the machine, so there are not as many facilities as in other programming languages.