si me acuerdo bien (sino, que alguien me corrija por favor jeje), desde el punto de vista del programador, la memoria esta dividida en 3 partes:
area del programa: contiene el codigo del cuerpo de las funciones y tambien las variables globales.
stack: las variables locales por ejemplo se guardan en el stack y se borran solas (ej. si dentro de una funcion sumar() declaras un "int a;", esa variable se guardara en el stack y luego al salir de esa funcion, saldra del stack automaticament)..esta parte de la memoria lo controla el sistema, uno nada mas declara las variables, y el sistema se encarga de alocar y dealocar espacio para ellas. Mas precisamente, en el stack se guardan las variables locales no estaticas. Se dice que esta parte de la memoria es eficiente porque es reutilizable (el mismo espacio se usa para distintas variables a lo largo de la ejecucion del programa).
heap: aca el programador es el que se encarga de alocar y dealocar espacio para las variables, si no las borras, quedan ahi volando en el aire y ocupando memoria. Basicamente (ej. de c++), cuando haces un new() o delete(), estas alocando espacio en el heap.
pd. en el caso de los punteros, los punteros en si se guardan en el stack mientras que los valores hacia el cual apunta se guardan en el heap