Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Asignaciondinamicamemoria 2011 PDF
Asignaciondinamicamemoria 2011 PDF
UNAN LEON
Departamento de Computacin
Ing. En Sistemas de Informacin
Autor:
Ing: Karina Esquivel Alvarado.
Asignatura:
Programacin Estructurada.
8.1 INTRODUCCIN
Los programas pueden crear variables globales o locales. Las variables declaradas globales
en sus programas se almacenan en posiciones fijas de memoria, en la zona conocida como
segmento de datos del programa, y todas las funciones pueden utilizar estas variables. Las
variables locales se almacenan en la pila (stack) y existen slo mientras estn activas las
funciones que estn declaradas.
Todas estas clases de variables comparten una caracterstica comn: se definen cuando se
compila el programa. Esto significa que el compilador reserva (define) espacio para
almacenar valores de los tipos de datos declarados. Es decir, en el caso de las variables
globales y locales se ha de indicar al compilador exactamente cuntas y de qu tipo son las
variables a asignar. O sea, el espacio de almacenamiento se reserva en el momento de la
Compilacin.
Sin embargo, no siempre es posible conocer con antelacin a la ejecucin cuanta memoria se
debe reservar al programa. En C, se asigna memoria en el momento de la ejecucin en el
montculo o montn (heap), mediante las funciones malloc(), realloc( ), calloc( ) y free( ),
que asignan y liberan la memoria de una zona denominada almacn libre.
Por ejemplo, la sentencia: int asignatura [40]; reserva 40 enteros, un nmero fijo de
elementos. Los arrays son un mtodo muy eficaz cuando se conoce su longitud o tamao en el
momento de escribir el programa. Sin embargo, presentan un grave inconveniente si el
tamao del array slo se conoce en el momento de la ejecucin. Las sentencias siguientes
produciran un error durante la compilacin:
Ya que el compilador requiere que el tamao del array sea constante. Sin embargo, en
numerosas ocasiones no se conoce la memoria necesaria hasta el momento de la ejecucin.
2
Asignacin Dinmica de Memoria en C
Por ejemplo, si se desea almacenar una cadena de caracteres tecleada por el usuario, no se
puede prever, a priori, el tamao del array necesario, a menos que se reserve un array de
gran dimensin y se malgaste memoria cuando no se utilice. En el ejemplo anterior, si el
nmero de alumnos de la clase aumenta, se debe variar la longitud del array y volver a
compilar el programa. El mtodo para resolver este inconveniente es recurrir a punteros y a
tcnicas de asignacin dinmica de memoria.
Por ejemplo:
int *p;
p = (int *) malloc(4);
3
Asignacin Dinmica de Memoria en C
El operador unario sizeof se utiliza con mucha frecuencia en las funciones de asignacin de
memoria. El operador se aplica a un tipo de dato (o una variable), el valor resultante es el
nmero de bytes que ocupa.
Al llamar a la funcin malloc( ) puede ocurrir que no haya memoria disponible, en ese caso
malloc( ) devuelve NULL.
El siguiente cdigo utiliza malloc( ) para asignar espacio para un valor entero:
int *pEnt;
pEnt = (int *) malloc(sizeof(int));
As, por ejemplo, para reservar memoria para un array de 100 nmeros reales:
float *BloqueMem;
BloqueMem = (float*) malloc (100*sizeof(float));
4
Asignacin Dinmica de Memoria en C
Ejemplo #1: Este programa lee una lnea de caracteres, reserva memoria para un
buffer de tantos caracteres como los ledos y se copia en el buffer la cadena.
//cadena.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void main()
{
char cad[21], *ptr ;
int lon ;
puts(\nIntroduce una linea de texto:) ;
gets(cad) ;
lon = strlen(cad); //Calcula la longitud de la cadena
ptr = (char *)malloc( (lon+1) * sizeof (char));
/*Devuelve un puntero que apunta a una seccin de memoria capaz de contener la cadena de
longitud strlen ( ) ms un byte extra por el carcter \0 al final de la cadena*/
strcpy (ptr, cad); //copia cad a nueva rea de memoria
printf ("ptr--> %s\n\n",ptr); /*cad est ahora en ptr*/
free(ptr) ; /*libera memoria apuntada por ptr*/
}
Ejemplo de Salida:
5
Asignacin Dinmica de Memoria en C
Ejemplo #2: Programa que crea un array de N valores de tipo entero de forma
dinmica.
//array_uni_dinamico.c
#include <stdio.h>
#include <stdlib.h>
void main()
{
int *ptr,nelem,i;
for(i=0;i<nelem;i++)
{
printf("Elemento[%d]:",i+1);
scanf("%d",(ptr+i));
}
printf("\n***ELEMENTOS DEL ARRAY***\n");
for(i=0;i<nelem;i++)
{
printf("%d ",*(ptr+i));
}
free(ptr); //Liberacin de memoria apuntada por ptr
}
6
Asignacin Dinmica de Memoria en C
Ejemplo de Salida:
Un array bidimensional es, en realidad, un array cuyos elementos son arrays. Al ser el
nombre de un array unidimensional un puntero constante, un array bidimensinal ser un
puntero a puntero constante (tipo **).
Para asignar memoria a un array multidimensional, se indica cada dimensin del array de igual
forma que se declara un array unidimensional.
Ejemplo #3: Programa en C que reserva memoria en tiempo de ejecucin para una
matriz de n filas y para cada fila m elementos.
//array_bidi_dinamico.c
#include <stdio.h>
#include <stdlib.h>
void main()
{
int **p; //Puntero a Puntero
int n,m,i,j,k;
do
{
printf ("\nCuantas filas?");
scanf ("%d",&n);
} while(n <=1);
7
Asignacin Dinmica de Memoria en C
//Reserva memoria para un array de n elementos, cada elemento es un puntero a entero (int *)
p = (int **) malloc(n * sizeof(int *));
if(p==NULL)
{
printf("Insuficiente Espacio de Memoria");
exit(-1);
}
for(i=0; i<n; i++)
{
printf("\n\nNumero de elementos de fila %d:", i+1) ;
scanf("%d",&m) ;
8
Asignacin Dinmica de Memoria en C
Ejemplo de Salida:
Adems de la funcin malloc( ) para obtener bloques de memoria, hay otras dos funciones
que permiten obtener memoria libre en tiempo de ejecucin, stas son calloc( ) y realloc( ).
Con ambas se puede asignar memoria, lo que cambia en relacin a la funcin malloc( ) es la
forma de transmitir el nmero de bytes de memoria requeridos. Ambas devuelven un
puntero al bloque asignado de memoria. El puntero se utiliza para referenciar el bloque de
memoria. El puntero que devuelven es del tipo void *.
9
Asignacin Dinmica de Memoria en C
La funcin calloc( ) est declarada en el archivo de cabecera stdlib.h, por lo que ser
necesario incluir ese archivo de cabecera en todo programa que llame a la funcin. Se puede
reservar memoria dinmicamente para cualquier tipo de dato, incluyendo char, float, arrays,
estructuras e identificadores de typedef.
Ejemplo #4: Este programa lee una lnea de caracteres, reserva memoria con la
funcin calloc( ) para un buffer de tantos caracteres como los ledos y se copia en el
buffer la cadena.
//funcion_calloc.c
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{
char *c, B[121];
puts("Introduce una cadena de caracteres:");
gets (B);
/*Se reserva memoria para el nmero de caracteres + 1 para el carcter*/
c = (char*) calloc (strlen(B)+1,sizeof( char));
//Copia la cadena leda en c
strcpy(c,B);
printf("\nc--> %s\n",c);
//Liberacin de Memoria
free(c);
}
10
Asignacin Dinmica de Memoria en C
Ejemplo de Salida:
//calloc_fn.c
#include <stdlib.h>
#include <stdio.h>
void main(void)
{
float *pf=NULL;
int num, i;
do
{
printf("Cuantos datos en el array?");
scanf ( "%d",&num) ;
}while (num<1);
11
Asignacin Dinmica de Memoria en C
Ejemplo de Salida:
Esta funcin tambin es para asignar un bloque de memoria libre. Tiene una variacin
respecto a malloc( ) y calloc( ), permite ampliar un bloque de memoria reservado
anteriormente.
12
Asignacin Dinmica de Memoria en C
Ejemplo #6: Programa en C que permite reservar memoria para una cadena y a
continuacin, ampliar para otra cadena ms larga utilizando la funcin realloc( ).
//realloc_fn.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main( )
{
char *cadena;
int tam;
tam = (strlen("Practicas")+ 1) * sizeof (char);
cadena = (char *) malloc (tam);
strcpy (cadena,"Practicas") ;
puts (cadena) ;
//Ampliacin del bloque de memoria
tam += (strlen("Profesionales\n")+ 1)* sizeof (char);
cadena = (char * ) realloc (cadena, tam);
strcat (cadena," Profesionales\n");
puts(cadena);
//Liberacin de memoria
free (cadena) ;
}
Ejemplo de Salida:
Ejemplo #7: Este programa lee n lneas de texto, reserva memoria segn la longitud de
la lnea leda, cuenta las vocales de cada lnea e imprime cada lnea y el nmero de
vocales que tiene. El programa declara char *cad[N] como array de punteros a char,
de tal forma que en la funcin entrada( ) se reserva memoria, con malloc( ), para cada
lnea de texto.
13
Asignacin Dinmica de Memoria en C
//cuenta_vocales.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define N 10
//Prototipos de Funciones
void salida(char *[ ], int *);
void entrada(char *[ ]);
int vocales(char *) ;
void main( )
{
char *cad[N];
int j, voc[N];
//Funcin para leer cadenas de caracteres
entrada (cad) ;
//Cuenta de vocales por cada cadena
for(j=0; j<N; j++)
voc[j] = vocales(cad[j]);
salida(cad, voc) ;
}
14
Asignacin Dinmica de Memoria en C
int j;
puts ("\n\tSalida de las cadenas junto al numero de vocales") ;
for (j=0; j<N; j++)
{
printf ("Cadena [%d]: %s tiene %d vocales\n",j+1,cd[j], v[j]);
}
}
15
Asignacin Dinmica de Memoria en C
Ejemplo de Salida:
Los punteros a estructuras se declaran igual que los punteros a otros tipos de datos. Para
referirse a un miembro de una estructura referenciado por un puntero es necesario utilizar
el operador ->.
Ejemplo #8: Programa que lee los datos de una estructura Deportista utilizando el
operador ->.
//deportista.c
#include<stdio.h>
#include<stdlib.h>
struct Deportista
{
char nombre [30];
float altura;
float peso;
};
16
Asignacin Dinmica de Memoria en C
void main( )
{
struct Deportista d,*dep;
dep = &d;
printf("Nombre: ");
scanf("%s",dep->nombre);
printf("Altura: ");
fflush(stdin);
scanf("%f",&dep->altura);
printf("Peso: ");
scanf("%f",&dep->peso);
Ejemplo de Salida:
Ejemplo #9: Este programa asigna memoria dinmica para un array de 3 estructuras
de tipo Estudiante y calcula cul es el estudiante que obtuvo la mayor nota.
//nota_mayor.c
#include<stdio.h>
#include<stdlib.h>
struct Estudiante
{
char nombre[30];
int nota;
};
17
Asignacin Dinmica de Memoria en C
void main()
{
struct Estudiante *est;
int i=1,j=1,pos,may;
18
Asignacin Dinmica de Memoria en C
Ejemplo de Salida:
19
Asignacin Dinmica de Memoria en C
else
{
for(n=1;n<=nest;n++)
{
printf("Nombre Estudiante: ");
fflush(stdin);
gets(est[n].nombre);
do
{
printf("Sexo(f/m): ");
fflush(stdin);
scanf("%c",&est[n].sexo);
}
while((est[n].sexo !='f' && est[n].sexo!='F') && (est[n].sexo !='m' && est[n].sexo!='M'));
if((est[n].sexo=='f') || (est[n].sexo=='F'))
nef++;
if((est[n].sexo=='m') || (est[n].sexo=='M'))
nem++;
printf("Nota: ");
scanf("%d",&est[n].nota);
20
Asignacin Dinmica de Memoria en C
Ejemplo de Salida:
Se puede asignar espacio para cualquier objeto dato de C. Las reglas para utilizar las
funciones malloc( ), calloc( ), realloc( ) y free( ) como medio para obtener/liberar espacio
de memoria son las siguientes:
2. Las funciones malloc( ) , calloc() , realloc( ) devuelven el tipo void *, lo cual exige
hacer una conversin al tipo del puntero.
4. El operador sizeof permite calcular el tamao de un tipo de objeto para el que est
asignando memoria.
21
Asignacin Dinmica de Memoria en C
Ejemplo:
struct punto
{
float x,y,z;
}
struct punto *p = (struct punto *)malloc (sizeof(struct punto));
void main()
{
struct complejo *pz;
int n;
22
Asignacin Dinmica de Memoria en C
scanf("%d",&n);
/*Puntero a estructura complejo*/
/*Asigna memoria para un array de tipo complejo*/
pz = (struct complejo *)calloc(n,sizeof(struct complejo));
if (pz == NULL)
{
puts ("Error de asignacin de memoria.") ;
exit(-1);
}
}
23