If we take, for example, a case of registration of a full name, as we have no way of knowing the amount of characters, we create the malloc()
, thus, the field will adjust to the exact size typed by the user, correct?
Generally no, it is common for you to set a maximum size that the name will have and allocate that amount. Eventually later optimizations can be made if necessary. You almost always choose whether you want to have the best memory consumption or the least processing possible.
It is possible to use a realloc()
, but in most cases it does not compensate for the effort. It increases the allocation as needed, but is almost always a worse solution. Example.
But in every example I see there is the insertion of the amount of bytes that will be allocated, example:
char *c = malloc(sizeof(char) * quantidade_de_elementos_que_vou_ter_no_meu_vetor;
I mean, in that case I’ll be allocating quantidade_de_elementos_que_vou_ter_no_meu_vetor
times the size of a char
. However, the object to use malloc()
, wouldn’t be because I don’t know the total amount of elements?
No, the purpose of its use is to allocate in dynamic memory, usually the heap (at least it is so in all "serious" implementations of standard C. Just this, you have to know the amount of bytes to be allocated.
That is, I don’t need to kick a static size, delimiting the maximum amount of elements. Using this variable quantidade_de_elementos_que_vou_ter_no_meu_vetor
does not take away that purpose?
Your concept of "static size" and every use of the static term out there is incorrect, static is something else, it is something that is immutable from the application startup and defined during compilation, so you cannot receive values at runtime.
Behold This prevents an array from being initialized with a variable size in C?. Or else How to store any string in C?.
And what is the size of char
? Is always 1, so I feel like crying when they use sizeof(char)
.
If I know the total amount of elements, what is the difference then of already defining a static size? Example:
char c[20];
This syntax determines that it is allocated in automatic memory (which is not static), i.e., the stack (so it will only exist in the scope where it was created). It is the only important difference to the malloc()
, not least because the malloc()
also requires a known size. There is no magic, there is no elasticity. See What is the difference between vector pointer and variable pointer?.
What I do know is that if I make a dynamic allocation, the memory allocation will be made in the execution of the program, not in its compilation, as occurs when there is a definition of a static vector.
In practice all allocation is done in execution. There is no allocation in compilation. There is defined allocation during the compilation that occurs in the static area. Even in the automatic area the size can be set at the time of need, and of course, it will be done only at execution. Something like this is allowed:
char c[x]; //x é lido pelo teclado antes desta linha
The reason you have to use an allocation of type:
char *c = malloc(sizeof(char) * quantidade_de_elementos_que_vou_ter_no_meu_vetor;
It would be because in C language, I need to know the size of my vector to get it runs the same?
No, that’s incorrect. Use it that way because you want the lifespan the object is detached from the lifetime of the function (the one in the automatic area) that created it, or you want to ensure that the size of the object does not create complicators for the stack which has a limited size, in which case you are assuring yourself because you know that potentially the object can be too big and even give a stack overflow.
Still using this line of code above as an example, if I say that:
quantidade_de_elementos_que_vou_ter_no_meu_vetor = 20;
This is just assigning the value 20
for a variable with a very long name that must already be declared in advance. The rest is speculation.
That means I will be allocating 20 bytes (sizeof(char) * 20, considering that the size of a char equals 1), right?
Yes.
What if in this case, I entered a word that had only 10 characters? Would I occupy only the first 10 spaces and the other 10? There would be a waste in this case then?
In a way, yes. I don’t know if you can call it waste, but in fact it’s unused. It’s normal. There are so many other "wastes" that most programmers never notice. There are cases that "waste" (overhead) of a vector in the stack is smaller, or at least not much larger than the use of malloc()
. Almost all implementations of malloc()
"waste" space (those who do not have other worse problems, so they are not actually used). Not to mention that it is much more complicated to manage it. And has a worse performance in almost all cases. It should always be the last option in most scenarios.
May be useful: