In C/C++ läuft das ein wenig anders:

malloc() legt intern verwaltete Speicherblöcke an und fordert neuen Speicher, wenn alles belegt ist oder eben nicht ausreicht.

free() gibt nur den Speicherblock frei, und trägt ihn in eine Kette der freien Blöcke ein, kann aber den Speicher nicht physisch freigeben.

Der nächste malloc() / realloc() sucht den nächsten freien passenden Block und belegt diesen dann, wenn nichts groß genug, wird eben neuer Speicher angefordert.

Der Speicher wird insgesamt erst freigegeben, wenn das Programm tatsächlich aus der Aktivierungsgruppe entfernt wird (ähnlich *INLR=*ON).

Je nach Implementation gibt es hier halt die berühmten Memory-Leaks, da durch ständiges malloc()/free() der Speicher stark fragmentiert werden kann.