Simulab
← Herramientas
Programación · C

Memoria y punteros en C

Avanza línea a línea y mira qué pasa en la pila y en el montón. Pasa el ratón por un puntero para ver a qué apunta.

Código en C
1#include <stdio.h>2 3void cambia(int n, int m)4{5    int aux;6    aux = m;7    m = n;8    n = aux;9    printf("En cambia: n=%d m=%d\n", n, m);10}11 12int main(void)13{14    int n = 10, m = 5;15    cambia(n, m);16    printf("En main:   n=%d m=%d\n", n, m);17    return 0;18}

Empieza main: se reserva su marco en la pila.

Pila (stack)crece hacia abajo ↓
marco de main · en ejecución

Sin variables todavía.

Montón (heap)malloc / free

Vacío: este programa no ha pedido memoria dinámica.

Salida
(sin salida todavía)

Direcciones simplificadas. ■ lo que acaba de cambiar · ■ a dónde apunta el puntero bajo el ratón

Qué es y cómo se usa

Un puntero es una variable que guarda una dirección de memoria. En C se usan para que una función modifique variables de quien la llama, para recorrer vectores y para trabajar con memoria dinámica. Aquí puedes ejecutar programas cortos línea a línea y ver la memoria por dentro.

La pila guarda las variables locales: cada llamada a una función crea un marco nuevo encima y lo destruye al terminar. El montón (heap) guarda lo que se pide con malloc, que sigue ahí hasta que se libera con free, aunque la función que lo pidió ya haya terminado.

Elige un programa y avanza paso a paso. Lo que acaba de cambiar se resalta, y si pasas el ratón por un puntero (o lo tocas en el móvil) se marca la variable o la casilla a la que apunta.

Ejemplo resuelto

¿Por qué cambia(n, m) no intercambia n y m en main, y cambia(&n, &m) sí?

  1. En C los argumentos se pasan por valor: la función recibe una copia en su propio marco de la pila.
  2. cambia(n, m) intercambia sus copias, que desaparecen al volver a main. Las variables de main no se tocan.
  3. cambia(&n, &m) recibe las direcciones de n y m. Con *n y *m lee y escribe en las variables de main.

Para que una función modifique una variable, hay que pasarle su dirección (paso por referencia)

Preguntas frecuentes

¿Qué diferencia hay entre * y & en C?

&x da la dirección de la variable x. *p da la variable a la que apunta p. En una declaración, int *p significa que p es un puntero a int.

¿Por qué pb++ avanza 4 bytes y no 1?

La aritmética de punteros va en elementos, no en bytes: sumar 1 a un int * avanza sizeof(int), que suele ser 4. Por eso V[i] y *(V + i) son lo mismo.

¿Qué es un puntero colgante?

Un puntero que guarda la dirección de memoria ya liberada, por ejemplo después de free. Usarlo es un error aunque parezca funcionar. Por eso se suele poner a NULL justo después de free.

¿Cómo se reserva una matriz dinámica?

Con un int ** que apunta a un vector de f punteros, uno por fila, y un malloc de c enteros para cada fila. Al liberar se hace al revés: primero cada fila y luego el vector de punteros.