what happens to the other 7 int
s, they will be released from memory by the function realloc()
or the memory will leak?
It will be released. Technically the memory will not leak, but nothing guarantees that the release will provoke the reuse of this space. So even if there isn’t a leak there can be a waste of that memory, so it’s rare for someone to make a, realloc()
decreasing the size, since this is only useful for large portions, and also because it is common to need to increase the number of items soon after reducing.
In higher-level languages, you usually have structures that handle this well abstractly and do what’s best without the programmer having to interfere (you can do it optionally), in C the common is someone using some library that gives it or that one creates a structure that better handles that form. Doing this or even moving manually is common to have a strategy to reuse the items and the realloc()
is less applied loose in application code than you might imagine. Incredible as it seems it’s usually best to waste a little space. It is only worth decreasing if you are sure that you will not need to grow again and the gain is expressive and necessary.
The realloc()
is mostly used to grow the object, because in general there will actually be a relocation. Decreasing the size of the object will not cause a relocation.
Memory fragmentation
One of the ways this happens is precisely to release a portion of memory (realloc()
is only one of the techniques) and it is unused because other objects can be larger than this liberated space. That’s bad, but it’s not tragic, and it’s more common than you think. In fact, unless you’re on a device with very scarce memory, it doesn’t pay to try to save that memory (for everything has an exception). The example quoted probably does not compensate, you save a few bytes and that may never be used again. But it can be used and be worse.
There’s another kind of fragmentation that is the fact that objects that are used together are in different places. If an object fits in this released space but another related space does not fit it will be placed in another point of memory, far from this, when accessing and the objects are separated will have two accesses and will probably be out of cache. Fragmentation worsens the reference location. When objects are together it is likely to be accessed more efficiently, when they are related.
You trade a little memory for performance.
In this specific case it makes sense to assign the return of realloc()
for a temporary variable
It makes sense in this restricted case. If it was another case I don’t know, it depends on context. Let’s say this was a function that does something more realistic and receives a pointer to an object and reduces its size. You couldn’t use the free()
, right?
If it is certain that you are reducing the size there can be no failure. Nothing in the specification says that it cannot fail, but we know that it does not fail, because if it was not so it would probably almost never relocate to reduce the size, because the cost would be too high. If you’re doing it in C, you’re usually looking for performance. In normal implementations you can count that there will be no failure and no need to assign anything extra or test if the reduction worked (in theory the code will not be 100% portable, but in practice it is, it would be the same as the staff says that stack and heap are implementation details, but in practice everyone develops thinking that they exist and have universally known semantics). Some guards can be interesting if you use this undocumented behavior and know that the code can run on any compiler, even the most "crazy".
Just be careful not to use the original variable after giving the realloc()
and before reassigning it, as you did correctly, so if you use temporary variable always use this pattern to reassign right after the test.
Completion
If you want to know more read the documentation. It’s not official, but it’s like it is, it’s where there’s curated good C/C professionals++.
The example is not good to show how things happen in the real world. It serves to show the mechanism, just have clear this difference not to reproduce the same behavior in real code.