Когда вызывается malloc() или new, то на самом деле вызывается какая-то win api функция?
Нет, не всегда. В большинстве случаев не вызывается. Системный вызов осуществляется только если текущий блок, управляемый сишной кучей (т.е. сишным рантаймом) исчерпывается. Если б каждый раз делался системный вызов, вы б не дождались результатов работы вашей программы.
И при удалении тоже?
См. выше.
И вот интересно, а как сделать маленькую кучу, чтобы память выделялась в пределах этой маленькой кучи только?
Выделяете блок памяти любым из известных вам способов, декларируете функции а-ля myalloc и myfree, и реализуете один из алгоритмов управления свободным пространством в куче (например, двоичного разбиения).
В C++ можно переопределить операторы new и delete.