Descargar

Estructuras de datos, Gestión Dinámica de Memoria


Partes: 1, 2

  1. Introducción
  2. El tipo de datos Puntero
  3. Definición
  4. Declaración de variables puntero
  5. Asignación errónea Cannot assign
  6. Operaciones con Punteros
  7. Diferencia entre punteros y variables
  8. Funciones de reserva de memoria: new
  9. Listas encadenadas o enlazadas
  10. Otras clases de listas enlazadas

Introducción

En este tema se estudiarán las posibilidades que ofrece el Lenguaje C a la hora de trabajar dinámicamente con la memoria dentro de los programas, esto es, reservar y liberar bloques de memoria al momento de ejecutar un programa.

Además en este tema se introducirá el concepto de tipo abstracto de dato y la forma de dividir un gran programa en otros más pequeños.

Los tipos de datos vistos hasta ahora, tanto los simples (Predefinidos por el lenguaje) como los estructurados (Definidos por el programador), sirven para describir datos o estructuras de datos cuyos tamaños y formas se conocen de antemano. Cuando se declara una variable se reserva la memoria suficiente para contener la información que debe almacenar. Esta memoria permanece asignada a la variable hasta que termine la ejecución del programa (fin de la función main). Sin embargo, hay programas cuyas estructuras de datos pueden variar de forma y tamaño durante la existencia del mismo (En modo ejecución).

Las variables de todos los tipos de datos vistos son variables estáticas, en el sentido de que se declaran en el programa, se designan por medio del identificador declarado (variable), y se reserva para ellas un espacio en memoria en tiempo de compilación. El contenido de la variable podrá cambiar durante la ejecución del programa, pero no el tamaño de memoria reservado para determinada variable.

En ocasiones el tamaño de los objetos no se conoce hasta el momento de la compilación. Por ejemplo, la longitud de una cadena de caracteres que introducirá el usuario no se conoce hasta el tiempo de ejecución. El tamaño de un arreglo puede depender de un parámetro cuyo valor se desconoce previo al momento de ejecución. Ciertas estructuras de datos como listas enlazadas, pilas y colas utilizan memoria dinámica.

C++, ofrece la posibilidad de crear o destruir variables en tiempo de ejecución del programa, a medida que van siendo necesitadas durante la ejecución del mismo. Puesto que estas variables no son declaradas en el programa, no tienen nombre y se denominan variables anónimas. Si un lenguaje permite la creación de variables anónimas, debe también proporcionar una forma de referirse a estas variables, de modo que se les pueda asignar valores. Del mismo modo, debe proporcionar una forma de acceder a estas. Para ello C++ proporciona el tipo Puntero.

El tipo de datos Puntero

El tipo puntero y las variables declaradas de tipo puntero se comportan de forma diferente a las variables que se han estudiado en temas anteriores. Hasta ahora cuando se declaraba una variable de un determinado tipo, dicha variable podía contener directamente un valor de dicho tipo. Con el tipo puntero esto no es así.

Los punteros proporcionan la mayor parte de la potencia al C y C++, y marcan la principal diferencia con otros lenguajes de programación.

Una buena comprensión y un buen dominio de los punteros pondrán en sus manos una herramienta de gran potencia. Un conocimiento mediocre o incompleto te impedirá desarrollar programas eficaces.

Por eso se le dedicará especial atención y mucho espacio a los punteros. Es muy importante comprender bien cómo funcionan y cómo se usan.

Para entender qué es un puntero se da un repaso primero cómo se almacenan los datos en un ordenador.

La memoria de un ordenador está compuesta por unidades básicas llamadas bits. Cada bit sólo puede tomar dos valores, normalmente denominados alto y bajo, ó 1 y 0 (Estados lógicos). Pero trabajar con bits no es práctico, y por eso se agrupan.

Cada grupo de 8 bits forma un byte u octeto. En realidad el microprocesador, y por lo tanto el programa, sólo puede manejar directamente bytes o grupos de dos o cuatro bytes. Para acceder a los bits hay que acceder antes a los bytes. Y aquí se llega al asunto, cada byte tiene una dirección, llamada normalmente dirección de memoria (compuesta por un segmento y un desplazamiento).

La unidad de información básica es la palabra, dependiendo del tipo de microprocesador una palabra puede estar compuesta por dos, cuatro, ocho o dieciséis bytes. Se hablará en estos casos de plataformas de 16, 32, 64 ó 128 bits. Se habla indistintamente de direcciones de memoria, aunque las palabras sean de distinta longitud. Cada dirección de memoria contiene siempre un byte (Una dirección de memoria corresponde únicamente a un byte). Lo que sucederá cuando las palabras sean de 32 bits es que se accede a posiciones de memoria que serán múltiplos de 4.

Todo esto sucede en el interior de la máquina, e imteresa más bien poco. Se puede saber qué tipo de plataforma se usa averiguando el tamaño del tipo int, y para ello hay que usar el operador "sizeof()", por ejemplo:

cout << "Plataforma de " << 8*sizeof(int) << " bits";

Definición

Un puntero es un tipo especial de variable que contiene, ni más ni menos que, una dirección de memoria. Por supuesto, a partir de esa dirección de memoria puede haber cualquier tipo de objeto (o dato): un char, un int, un float, un array, una estructura, una función u otro puntero. El programador será el responsables de decidir ese contenido.

Partes: 1, 2
Página siguiente