[Tutorial C] VI - Asignación dinámica de memoria

Ver el tema anterior Ver el tema siguiente Ir abajo

[Tutorial C] VI - Asignación dinámica de memoria

Mensaje  HarZe el Jue Jun 25, 2009 4:14 pm

Asignación dinámica de memoria

Hasta ahora estamos trabajando con variables fijas, no dejamos libertad a que el usuario pueda crear distintas variables según su interes. Es un poco dificl de explicar así, así que pondré un ejemplo: imagina que quieres hacer un codificador de texto, no sabes cuanto espacio vas a necesitar en memoria hasta que el usuario mete el texto, que puede ser una palabra o un libro entero. La solución de novato es poner un char[10000], pero incluso así nos podemos quedar cortos, y en caso de tener que descrifrar una palabra, sobra demasiado espacio. Tenemos que poder cambiar las variables y crearlas en función de lo que suceda, ¿no? De eso trata esta lección.

Las funciones malloc(), realloc(), calloc() y free(), de la liberia stdlib.h, o malloc.h se encargan de realizar esta tarea. Todos los datos se almacenan en el almacén libre (heap), que es una pila limitada a 64K en un principio, todo esto varía de la maquina. Todas las variables que declarabas hasta ahora iban a la pila, ahora tu dirás a donde van, de un modo indirecto.

malloc()
( MALLOC viene de Memory ALLOCation, alojamiento en la memoria)

Con esta función, se obtiene un puntero que apunta a un bloque asignado de memoria. Su estructura es:
Código:
puntero = (tipo) malloc(tamaño en bytes);
Un ejemplo:
Código:
int *p;
p = (int*) malloc(sizeof(int));
*p = 5;
Primero declaramos un puntero, que aún no apunta a ningún sitio. Luego, el puntero, no su contenido, sino el propio puntero, es igual a un puntero tipo int que contiene la dirección en memoria con espacio para un int. La función sizeof() obtiene el espacio que ocupa aquello que quieras, si dentro pones int, como son 2 bytes, pues hemos asignado dos bytes. Esta función también sirve para obtener el tamaño de punteros, variables o lo que haga falta.
Por último, ahora que el puntero tiene contenido, le damos un valor.

Ahora, no solo podemos crear variables de la nada, sino tablas de la nada, o mejor dicho, tablas dinámicas, cuyo espacio no es fijio y puede cambiar, e incluso desaparecer ( ver free() ). Veamos un ejemplo concreto:
Código:
//Tabla típica
int tabla[256];

//Tabla dinámica
int *tab;
tab = (int*) malloc(256*sizeof(int));
Explicación: (que a esto quería yo llegar) las tablas normales ya están explicadas, pero las dinámicas no. Si has seguido mis tutos, por lo que sabes, esto es correcto:
Código:
int a;
scanf("%i",&a);
int tabla[a];
Y te crees que has hecho una tabla de un número de elementos determinados por el numero que has introducido antes, FALSO, las declaraciones de variables NO PUEDEN depender tan directamente de valores externos. La forma correcta es:
Código:
tabla = (int*) malloc(numero_de_elementos*sizeof(int));
Y para editar esas tablas que has creado así, no es distinto a antes:
Código:
int *tab;
tab = (int*) malloc(256*sizeof(int));
tab[34] = 5;
Un ejemplo de tablas multidimensional:
Código:
int **tab;
tab = (int **) malloc(10*sizeof(int*));
tab[3] = (int*) malloc(10*sizeof(int));
tab[3][4] = 5;

free()

Si un malloc() no encuentra sitio en la memoria, devuelve nulo ( cero ). Para que no ocurra, existe esta función que libera bloques usados por la función malloc() antes descrita. Como esa función ocupa un bloque con un puntero, free() lo libera para que pueda ser usado por otro. Estructura:
Código:
free(puntero);
Atendiendo al ejemplo anterior:
Código:
int **tab;
tab = (int **) malloc(10*sizeof(int*));
tab[3] = (int*) malloc(10*sizeof(int));
tab[3][4] = 5;
free(tab);
Sencillo, ¿no?

calloc()

Es como un malloc() pero más especializado, lo puedes comprobar son su estructura:
Código:
puntero = (tipo) calloc(numero_elementos,tamaño_por_elemento);
Por ejemplo:
Código:
int *p;
p = (int*) calloc(50,sizeof(int));
Personalmente, no necesito usarlo.

realloc()

Esta función si presenta una novedad. Permite ampliar con espacio libre un bloque de espacio ya existente. Puedes crear un bloque de memoria y su puntero, con malloc() o calloc(), y luego puedes ampliar ese bloque. Su estructura es:
Código:
puntero = realloc(puntero_de_bloque, tamaño_a_añadir);
Esto tiene un montón de aplicaciones, y la gran mayoría va unido a texto, pues suele ser el dato que previamente no sabemos cuánto será aumentado. No me voy a complicar en poner un ejemplo concreto:
Código:
char *p;
p = (char*) malloc(30*sizeof(char));
p = (char*) realloc(p, 15*sizeof(char));
Al final tiene 45 bytes de espacio.

HarZe
WebMaster & Desarrollador

Cantidad de envíos : 58
Fecha de inscripción : 21/06/2009
Edad : 24

Ver perfil de usuario http://opengl-esp.superforo.net

Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba

- Temas similares

 
Permisos de este foro:
No puedes responder a temas en este foro.