OK, I think I understand the confusion here.
__end_of_heap indicates the current end of the heap - but this includes any last block that has been free'd. In other words it effectively provides the maximal extent of the the heap so far, not the end of the currently "active" last block.
In the K22 example posted above by EmilioBrivio, the code first of all calls printf - which causes a small amount of heap space to be grabbed (to hold the character string that is then passed out to the debugger console over semihosting, as one block). At the end of printf, that heap space is free'd. But __end_of_heap stays pointing to the maximum extent of the heap so far.
Then when the example code tries to grab just a few characters worth of heap space, this heap request can be fulfilled using the free'd block. So there is no need to extend the heap further.
If you try grabbing making additional or larger calls into malloc(), you will see __end_of_heap does then increase.
We'll look at improving the IDE documentation for a future release to encompass the above details.
Regards,
MCUXpresso IDE Support