Una de las cosas en las que un buen número de personas se ve confundida al estar programando en lenguajes como C o C++, es la que está relacionada con los apuntadores. Temas como el manejo de memoria resultan complicados para algunos por su aparente dificultad pero, a decir verdad, no hay nada que temer sobre ellos, basta comprender los conceptos básicos e ir poniendo manos a la obra.
Hablar sobre apuntadores nos lleva a hablar directamente sobre la memoria principal de nuestra computadora, por tanto, vale la pena primero conocer lo básico de este elemento con tal de ir construyendo una buena base sobre la que podamos colocar todo aquello que aprendamos en las notas siguientes que conforman esta serie.
Encontrarás en esta nota:
La memoria principal
La memoria RAM, también conocida como memoria primaria, memoria interna, o memoria principal, es un dispositivo donde se almacenan los datos de algún programa para que estos sean fácilmente accedidos por el procesador. El almacenamiento que ocurre no es permanente, cada vez que apagamos nuestro equipo, la información contenida en esta memoria se pierde.
Aunque la capacidad de almacenamiento en una memoria RAM es menor que si la comparamos con algún otro dispositivo como un disco duro, la velocidad de acceso a los datos por parte del procesador es mucho mayor en el primer caso.
Las unidades que suelen emplearse cuando se habla de velocidad de acceso son los nanosegundos (ns) o los microsegundos (µs). Para tener una idea más clara de lo que esto significa, pongamos las cosas en perspectiva: si al procesador le tomara 10 segundos obtener un dato que se encuentra en memoria, para traerlo desde el disco duro le tomaría alrededor de ¡58 días! Con esto podemos ver cuál es el significado de decir que los accesos a disco son mucho más costosos.
Dirección de memoria
Observando a la memoria desde un mayor nivel de abstracción, podrías imaginarla como si de un gran conjunto de celdas se tratara, cada una de estas celdas estaría marcada por un número que las identifica y es a este número al que podríamos referirnos como: dirección de memoria. Si tenemos la dirección de memoria, podemos ubicar fácilmente la celda en cuestión y acceder a lo que esta contiene.
Ya que la información de una computadora se mide por bytes, es lógico pensar que cada celda disponible en la memoria tiene el tamaño de un byte. No todos los valores que podemos guardar en memoria tienen el mismo tamaño, por tanto, estos pueden abarcar desde un simple byte hasta varios bytes (pueden tomar una o varias celdas).
Imagina por un momento que declaramos tres variables de tipo entero en nuestro programa y que cada entero tiene un tamaño de 4 bytes. Si suponemos que el sistema reserva memoria para estas variables en espacios contiguos, tendríamos las siguientes direcciones que identifican al lugar que ocupa cada variable:
Puedes observar que cada dirección de memoria está separada precisamente por 4 unidades, si hubiéramos decidido que las variables fueran de algún tipo que tenga tamaño de un byte, cada dirección estaría separada por una sola unidad.
Tres tipos de memoria
Hasta ahora hemos visto que los valores con los que trabaja nuestro programa deben encontrarse en la memoria, que cada uno tendrá su espacio reservado y que cada espacio tendrá su identificador o dirección. Ya que la memoria es un recurso limitado, no podemos pensar que las variables que declaremos permanezcan eternamente en ella, habrá que abandonar el espacio una vez que se haya terminado de trabajar con estas variables.
La memoria se clasifica en tres tipos diferentes que decidirán el tiempo en que una variable permanecerá en ella. Veamos cada una:
Memoria estática o global
En este tipo de memoria estarán aquellas variables cuyo tiempo de vida corresponde con el del programa, es decir, estas variables aparecerán en memoria al iniciar el programa y ahí permanecerán hasta que este termine.
Memoria automática
Las variables de esta región están atadas al tiempo de vida de la función donde son declaradas. Cuando se llama a una función, las variables que en ella se encuentran toman su lugar en memoria y ahí permanecen hasta que la función termina.
Memoria dinámica
Existe una región de la memoria que se conoce como heap, aquí reside memoria que puede ser tomada por tu programa en tiempo de ejecución. Las variables que residan en algún espacio que fue tomado de esta manera, permanecerán ahí hasta que el programador decida liberar dicho espacio. No te preocupes si esto no queda claro en este momento, lo retomaremos más adelante con más detalle.
Resumiendo lo anterior, aquí te dejo una tabla con los puntos importantes:
Tipo de memoria | Tiempo de vida de las variables |
---|---|
Global / Estática | Durante todo el tiempo de vida del programa. |
Automática | Durante la ejecución de la función donde son declaradas. |
Dinámica | Hasta que el programador decida liberar el espacio. |
Para terminar
Manipular datos que se encuentran en memoria es la principal razón de ser de los apuntadores, por tal motivo, confío en que esta introducción haya servido para ofrecerte un conocimiento básico sobre qué es la memoria, cómo se organiza y de qué manera funciona; todo esto son los primeros pasos para comprender mejor lo que vendrá en notas posteriores.
En la siguiente entrega de esta serie daremos respuesta a la pregunta: ¿qué son los apuntadores? Veremos cómo declararlos, cómo obtener direcciones de memoria, entre varias cosas más. Quédate al pendiente y recuerda que cualquier duda puedes dejarla en los comentarios.
Hasta la próxima.
Hola! Oye gracias por aportar este serie es muy importante de la manera que lo hacen debido a que no hay información de calidad en la web, seria genial que montaran desde cero una seria de todas las formas declarar un ciclo, o una estructura secuencial if no se si me haga explicar por ejemplo he visto ciclo for como este for(i = 0; i < 9 && t == q; i++) cuando uno ve este tipo de ciclos se le pega la refundida del siglo.
Muy buena analogia con el casillero, me pregunto que habra mas a bojo nivel, como los lenguajes gestionan la memoria?