Lenguaje C
Punteros y
Memoria Dinámica
1
Punteros
Un puntero es una variable que contiene una
dirección de memoria (donde posiblemente se almacene
el valor de otra variable).
Para declarar punteros, se utiliza el operador *
(Pascal: ^) como se muestra a continuación:
int main() {
int a = 10;
int *p; La variable p es de tipo
... “puntero a int”
2
Punteros
Operador Unitario & me la dirección de un dato en la
memoria.
Dirección de memoria
int main() { de “a”se asigna a p.
int a = 10;
int *p;
p = &a;
printf(“Valor de p:%d “, p);
printf(“Valor que apunta p:%d “, *p);
printf(“Dirección de p:%d “, &p);
}
3
Punteros y Arreglos
Cuando se declara un arreglo, se reserva un solo
bloque contiguo de memoria para almacenar
todos sus elementos, y éstos se almacenan en la
memoria en el mismo orden que ocupan en el
arreglo:
int main() {
int i, a[10];
for (i = 0; i < 10; i++) {
printf (“%d”, &a[i] );
}
return 0; 4
}
Punteros y Arreglos
En C, el nombre de un arreglo es también un puntero al primer elemento
del arreglo.
De hecho, el lenguaje C no puede distinguir entre un arreglo y un puntero:
ambos son completamente intercambiables.
int main() {
int i, a[10], *p;
for (i = 0; i < 10; i++) { a[i] = i; };
p = a;
for (i = 0; i < 10; i++) {
Printf(“%d”, p[i]);
}
return 0;
5
}
Asignación Dinámica de Memoria
Reserva de memoria de manera dinámica (durante la
ejecución). Ejemplo: “creación de una agenda”.
Los datos creados dinámicamente se pueden organizar de
alguna manera. Por ej. “Listas simplemente enlazadas”.
Previamente definimos una estructura de datos:
struct _agenda { struct dato {
struct dato info; char nombre[20];
struct _agenda *siguiente; char telefono[12];
}; };
6
Asignación Dinámica de Memoria
Siempre debemos tener un puntero del tipo _agenda para
recordar la posición en memoria del primer elemento de la
lista. Si perdemos este puntero perderemos la lista completa.
struct _agenda *primero;
Opcionalmente podemos tener también un puntero al último elemento de la lista.
struct _agenda *ultimo;
Para añadir un elemento a la lista primero debemos crear
dinámicamente el dato con malloc.(Pascal: new).
struct _agenda *nuevo;
nuevo = (struct _agenda *) malloc (sizeof(struct _agenda));
if (nuevo==NULL) printf( "No hay memoria disponible!\n");
7
Asignación Dinámica de Memoria
Acceso a los campos de la estructura.
(nuevo->info).nombre = “Juan”;
(nuevo->info).telefono = “46464646”;
nuevo->siguiente = NULL /* preparamos el dato para luego
insertarlo al
último de la lista enlazada */
NULL: “a ninguna parte”.
8
Asignación Dinámica de Memoria
Insertar el elemento al último de la lista
/* comprobamos si la lista está vacía. si primero==NULL es que no
hay ningún elemento en la lista. también vale ultimo==NULL */
if (primero==NULL) {
printf( "Primer elemento\n");
primero = nuevo;
ultimo = nuevo;
else {
/* el que hasta ahora era el último tiene que apuntar al nuevo */
ultimo->siguiente = nuevo;
/* hacemos que el nuevo sea ahora el último */
ultimo = nuevo;
9
}
Asignación Dinámica de Memoria
Mostrar la lista completa
void mostrar_lista() {
struct _agenda *auxiliar; /* lo usamos para recorrer la lista */
int i;
i=0;
auxiliar = primero;
printf("\nMostrando la lista completa:\n");
while (auxiliar!=NULL) {
printf( "Nombre: %s, Telefono: %s\n",
(auxiliar->info).nombre, (auxiliar->info).telefono);
auxiliar = auxiliar->siguiente;
i++;
if (i==0) printf( "\nLa lista está vacía!!\n" ); 10
}
Asignación Dinámica de Memoria
Liberar Memoria
Cuando un elemento no se requiere mas debe eliminarse para liberar la
memoria reservada: free(puntero al elemento) (en Pascal: dispose).
free(ptr);
Ejemplo:
struct _agenda *nuevo;
nuevo = (struct _agenda *) malloc (sizeof(struct _agenda));
if (nuevo==NULL)
printf( "No hay memoria disponible!\n");
else {
.....
free(nuevo); /* finalmente, libera la zona de memoria */
11
}
Asignación Dinámica de Memoria
Errores Comunes
Generación de basura
#include <stdlib.h>
int* ptr; /* puntero a enteros */
int* ptr2; /* otro puntero */
...
ptr = (int*)malloc (sizeof(int) );
ptr2 = (int*)malloc (sizeof(int) );
*ptr = 15;
*ptr2 = 20;
ptr2 = ptr; /* asignación a otro puntero */
printf(“%d”,*ptr2);
/* finalmente, libera la zona de memoria */ 12
free(ptr);
Asignación Dinámica de Memoria
Errores Comunes
Referencias Colgadas
#include <stdlib.h>
int* ptr; /* puntero a enteros */
int* ptr2; /* otro puntero */
...
ptr = (int*)malloc (sizeof(int) );
ptr2 = (int*)malloc (sizeof(int) );
*ptr = 15;
ptr2 = ptr; /* asignación a otro puntero */
free(ptr);
....
13
printf(“%d”,*ptr2);
Administración de la Memoria
La administración de memoria de una computadora es una
tarea fundamental debido a que la cantidad de memoria es
limitada.
El sistema operativo es el encargado de administrar la
memoria del sistema y compartirla entre distintos usuarios y/o
aplicaciones.
14
Administración de la Memoria
La ejecución de un programa requiere que diversos
elementos se almacenen en la memoria:
Código del programa (instrucciones)
Datos
Permanentes
Temporales
Información para controlar de flujo del ejecución del
programa
15
Administración de la Memoria
Representación de un proceso (ejecución de un programa)
en memoria.
HEAP
Memoria disponible
para el controlar la
ejecución
Variables
Estáticas (ej. variables globales)
Código del Programa
16
Administración de la Memoria
Memoria Estática:
Define la cantidad de memoria necesaria para un programa durante el
tiempo de compilación.
El tamaño no puede cambiar durante el tiempo de ejecución del
programa.
Tampoco puede liberarse.
Algunos lenguajes de programación utilizan la palabra static para
especificar elementos del programa que deben almacenarse en
memoria estática.
17
Administración de la Memoria
Memoria Dinámica:
Las variables dinámicas son aquellas que crecen de tamaño o
se reducen durante la ejecución de un programa.
Estas se almacenan en un espacio de memoria llamado heap.
Algunos lenguajes de programación permiten que el
programador asigne y libere manualmente la memoria
(Pascal, C, etc.).
Java solo permite la creación de memoria pero no la
liberación. Utiliza un recolector de basura para liberar
memoria.
18
Administración de la Memoria
HEAP
Lista de bloques libres Lista de bloques ocupados
19
Memoria Dinámica
Ejercicios
- Considerando el ejemplo de la agenda definir las funciones:
a) insertar_primero(), inserta un elemento al comienzo de la agenda.
b) sumprimir_primero(), elimina el primer elemento de la agenda.
- Completar el programa agenda.c disponible en el aula virtual.
20
Referencias
http://www.tutorialspoint.com/cprogramming/c_quick_guide.htm
http://www.fismat.umich.mx/mn1/manual/manual.html
Capítulo 7 del apunte de la asignatura “Análisis Comparativo
de Lenguajes”. Archivo acl-book.pdf
21