Está en la página 1de 23

2011

UNAN – LEON
Departamento de Computación
Ing. En Sistemas de Información

Autor:
Ing: Karina Esquivel Alvarado.

Asignatura:
Programación Estructurada.

ASIGNACIÓN DINÁMICA DE MEMORIA


EN C
Asignación Dinámica de Memoria en C

TEMA 8: ASIGNACIÓN DINÁMICA DE MEMORIA

8.1 INTRODUCCIÓN

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 sólo mientras están activas las
funciones que están declaradas.

Todas estas clases de variables comparten una característica común: 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 cuántas y de qué tipo son las
variables a asignar. O sea, el espacio de almacenamiento se reserva en el momento de la
Compilación.
Sin embargo, no siempre es posible conocer con antelación a la ejecución cuanta memoria se
debe reservar al programa. En C, se asigna memoria en el momento de la ejecución en el
montículo o montón (heap), mediante las funciones malloc(), realloc( ), calloc( ) y free( ),
que asignan y liberan la memoria de una zona denominada almacén libre.

8.2 GESTIÓN DINÁMICA DE MEMORIA

Consideremos un programa que evalúe las calificaciones de los estudiantes de una


asignatura. El programa almacena cada una de las calificaciones en los elementos de una lista
o tabla (array) y el tamaño del array debe ser lo suficientemente grande para contener el
total de alumnos matriculados en la asignatura.

Por ejemplo, la sentencia: int asignatura [40]; reserva 40 enteros, un número fijo de
elementos. Los arrays son un método muy eficaz cuando se conoce su longitud o tamaño en el
momento de escribir el programa. Sin embargo, presentan un grave inconveniente si el
tamaño del array sólo se conoce en el momento de la ejecución. Las sentencias siguientes
producirían un error durante la compilación:

scanf (“%d” &num_estudiantes) ;


int asignatura[num_estudiantes] ;

Ya que el compilador requiere que el tamaño del array sea constante. Sin embargo, en
numerosas ocasiones no se conoce la memoria necesaria hasta el momento de la ejecución.

2
Asignación Dinámica 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 tamaño del array necesario, a menos que se reserve un array de
gran dimensión y se malgaste memoria cuando no se utilice. En el ejemplo anterior, si el
número de alumnos de la clase aumenta, se debe variar la longitud del array y volver a
compilar el programa. El método para resolver este inconveniente es recurrir a punteros y a
técnicas de asignación dinámica de memoria.

El espacio de la variable asignada dinámicamente se crea durante la ejecución del


programa, al contrario que en el caso de una variable local cuyo espacio se asigna en tiempo
de compilación. La asignación dinámica de memoria proporciona control directo sobre los
requisitos de memoria de su programa. El programa puede crear o destruir la asignación
dinámica en cualquier momento durante la ejecución. Se puede determinar la cantidad de
memoria necesaria en el momento en que se haga la asignación. Dependiendo del modelo de
memoria en uso, se pueden crear variables mayores de 64 K.

El código del programa compilado se sitúa en segmentos de memoria denominados segmentos


de código. Los datos del programa, tales como variables globales, se sitúan en un área
denominada segmento de datos. Las variables locales y la información de control del
programa se sitúan en un área denominada pila. La memoria que queda se denomina memoria
del montículo o almacén libre. Cuando el programa solicita memoria para una variable
dinámica, se asigna el espacio de memoria deseado desde el montículo.

8.3 FUNCIÓN malloc()

La forma más habitual de C para obtener bloques de memoria es mediante la llamada a la


función malloc( ). La función asigna un bloque de memoria que es el número de bytes pasados
como argumento. malloc( ) devuelve un puntero, que es la dirección del bloque asignado de
memoria. El puntero se utiliza para referenciar el bloque de memoria y devuelve un puntero
del tipo void *. La función malloc( ) está declarada en el archivo de cabecera stdlib.h.

La forma de llamar a la función malloc( ) es:


puntero = malloc(tamaño en bytes);

Generalmente se hará una conversión al tipo del puntero:


tipo *puntero;
puntero =(tipo *)malloc(tamaño en bytes);

Por ejemplo:
int *p;
p = (int *) malloc(4);

3
Asignación Dinámica de Memoria en C

El operador unario sizeof se utiliza con mucha frecuencia en las funciones de asignación de
memoria. El operador se aplica a un tipo de dato (o una variable), el valor resultante es el
número de bytes que ocupa.

Así, si se quiere reservar memoria para un buffer de 10 enteros:


int *r;
r = (int *) malloc(10*sizeof(int)) ;

Al llamar a la función malloc( ) puede ocurrir que no haya memoria disponible, en ese caso
malloc( ) devuelve NULL.

Sintaxis de llamada a malloc( )


tipo *puntero;
puntero = (tipo *)malloc(tamaño) ;

Prototipo que incluye malloc( )


void * malloc(size_t n );

En la sintaxis de llamada, puntero es el nombre de la variable puntero a la que se asigna la


dirección del objeto dato, o se le asigna la dirección de memoria de un bloque lo
suficientemente grande para contener un array de N elementos, o NULL, si falla la
operación de asignación de memoria.

El siguiente código utiliza malloc( ) para asignar espacio para un valor entero:
int *pEnt;
pEnt = (int *) malloc(sizeof(int));

La llamada a malloc( ) asigna espacio para un int (entero) y almacena la dirección de la


asignación en pEnt. pEnt apunta ahora a la posición en el almacén libre (montículo) donde se
establece la memoria.

Así, por ejemplo, para reservar memoria para un array de 100 números reales:
float *BloqueMem;
BloqueMem = (float*) malloc (100*sizeof(float));

En el ejemplo se declara un puntero denominado BloqueMern y lo inicializan a la dirección


devuelta por malloc( ). Si un bloque del tamaño solicitado está disponible, malloc( ) devuelve
un puntero al principio de un bloque de memoria del tamaño especificado. Si no hay bastante
espacio de almacenamiento dinámico para cumplir la petición, malloc( ) devuelve cero o NULL.

4
Asignación Dinámica de Memoria en C

La reserva de n caracteres se puede declarar así:


int ncaracteres;
char *s;
scanf("%d",&ncaracteres);
s = (char *) malloc(ncaracteres * sizeof(char));

Ejemplo #1: Este programa lee una línea de caracteres, reserva memoria para un
buffer de tantos caracteres como los leídos 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 sección de memoria capaz de contener la cadena de
longitud strlen ( ) más un byte extra por el carácter ‘\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
Asignación Dinámica de Memoria en C

Ejemplo #2: Programa que crea un array de N valores de tipo entero de forma
dinámica.
//array_uni_dinamico.c
#include <stdio.h>
#include <stdlib.h>
void main()
{
int *ptr,nelem,i;

printf("Cuantos elementos: ");


scanf("%d",&nelem);
ptr = (int *)malloc(nelem * sizeof (int)); //Memoria dinámica para N elementos
if(ptr == NULL)
{
printf("Insuficiente Espacio de Memoria");
exit(-1); //Salir del Programa
}

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); //Liberación de memoria apuntada por ptr
}

6
Asignación Dinámica de Memoria en C

Ejemplo de Salida:

8.3.1 USO DE MALLOC( ) PARA ARRAYS MULTIDIMENSIONALES

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 dimensión del array de igual
forma que se declara un array unidimensional.

Ejemplo #3: Programa en C que reserva memoria en tiempo de ejecución 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
Asignación Dinámica 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) ;

p[i] = (int *)malloc(m*sizeof (int));


if(p[i]==NULL)
{
printf("Insuficiente Espacio de Memoria");
exit(-1);
}

for (j=0; j<m;j++)


{
printf("Elemento[%d][%d]:",i+1,j+1);
scanf ("%d",&p[i][j]); //Lectura a través de Notación de array
}
printf("\nElementos de la Fila %d:\n", i+1) ;
for (k=0; k<m;k++)
//Impresión de los elementos del array a través Notación de Puntero
printf("%d ",*(*(p+i)+k)) ;
}
//Liberar la Memoria asignada a cada una de las filas
for (i=0; i<n; i++)
free(p[i]) ;
//Liberar la Memoria asignada a la Matriz de Punteros
free(p);
}

8
Asignación Dinámica de Memoria en C

Ejemplo de Salida:

8.4 LIBERACIÓN DE MEMORIA, FUNCIÓN free( )

Cuando se ha terminado de utilizar un bloque de memoria previamente asignado por malloc( ),


u otras funciones de asignación, se puede liberar el espacio de memoria y dejarlo disponible
para otros usos, mediante una llamada a la función free( ). El bloque de memoria suprimido
se devuelve al espacio de almacenamiento libre, de modo que habrá más memoria disponible
para asignar otros bloques de memoria.

El formato de la llamada es: free (puntero);

8.5 FUNCIONES DE ASIGNACIÓN DINÁMICA DE MEMORIA: calloc( ) y realloc( )

Además de la función malloc( ) para obtener bloques de memoria, hay otras dos funciones
que permiten obtener memoria libre en tiempo de ejecución, éstas son calloc( ) y realloc( ).
Con ambas se puede asignar memoria, lo que cambia en relación a la función malloc( ) es la
forma de transmitir el número 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 *.

8.5.1 FUNCIÓN: calloc( )

La forma de llamar a la función calloc( ) es:


puntero = calloc(Número elementos,tamaño de cada elemento);

9
Asignación Dinámica de Memoria en C

Generalmente se hará una conversión al tipo del puntero:


tipo *puntero;
puntero =(tipo *) calloc (numero elernentos,tamaño de cada elemento);

El tamaño de cada elemento se expresa en bytes, se utiliza para obtenerlo el operador


sizeof.

La función 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 función. Se puede
reservar memoria dinámicamente para cualquier tipo de dato, incluyendo char, float, arrays,
estructuras e identificadores de typedef.

Por ejemplo, se quiere reservar memoria para 5 datos de tipo double:


#define N 5
double *pd;
pd = (double *) calloc (N,sizeof(double)) ;

Ejemplo #4: Este programa lee una línea de caracteres, reserva memoria con la
función calloc( ) para un buffer de tantos caracteres como los leídos 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 número de caracteres + 1 para el carácter*/
c = (char*) calloc (strlen(B)+1,sizeof( char));
//Copia la cadena leída en c
strcpy(c,B);
printf("\nc--> %s\n",c);

//Liberación de Memoria
free(c);
}

10
Asignación Dinámica de Memoria en C

Ejemplo de Salida:

Ejemplo #5: En el siguiente programa se considera una secuencia de números reales,


con una variable puntero a float se procesa un array de longitud variable, de modo que
se puede ajustar la cantidad de memoria necesaria para el número de valores durante
la ejecución del programa.

//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);

//Asigna memoria: num*tamaño bytes


pf = (float *)calloc(num,sizeof(float));
if (pf == NULL)
{
puts("Error en la asignacion de memoria.");
exit(-1);
}
printf ("\nIntroduce %d valores de tipo decimal\n",num);
for (i=0; i<num; i++)
{
printf("Dato[%d]: ",i+1);
scanf("%f",&pf[i]) ;
}

11
Asignación Dinámica de Memoria en C

printf ("\nEn el array hay %d elementos\n",num) ;


for (i=0; i<num; i++)
printf("%.2f ",pf[i]) ;
printf("\n\n");
//Liberación de la memoria asignada de forma dinámica
free(pf);
}

Ejemplo de Salida:

8.5.2 FUNCIÓN: realloc( )

Esta función también es para asignar un bloque de memoria libre. Tiene una variación
respecto a malloc( ) y calloc( ), permite ampliar un bloque de memoria reservado
anteriormente.

La forma de llamar a la función realloc( ) es:


puntero = realloc (puntero a bloque, tamaño total de nuevo bloque);

Generalmente se hará una conversión al tipo del puntero:


tipo *puntero;
puntero =(tipo *) realloc (puntero a bloque,tamaño total nuevo bloque);

El tamaño del bloque se expresa en bytes. El puntero a bloque referencia a un bloque de


memoria reservado previamente con malloc( ) , calloc( ) o la propia realloc( ) .

12
Asignación Dinámica de Memoria en C

Ejemplo #6: Programa en C que permite reservar memoria para una cadena y a
continuación, ampliar para otra cadena más larga utilizando la función 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) ;
//Ampliación del bloque de memoria
tam += (strlen("Profesionales\n")+ 1)* sizeof (char);
cadena = (char * ) realloc (cadena, tam);
strcat (cadena," Profesionales\n");
puts(cadena);
//Liberación de memoria
free (cadena) ;
}

Ejemplo de Salida:

8.6 ASIGNACIÓN DE MEMORIA PARA ARRAYS

La gestión de listas y tablas mediante arrays es una de las operaciones más usuales en
cualquier programa. La asignación de memoria para arrays es, en consecuencia, una de las
tareas que es preciso conocer en profundidad.

Ejemplo #7: Este programa lee n líneas de texto, reserva memoria según la longitud de
la línea leída, cuenta las vocales de cada línea e imprime cada línea y el número de
vocales que tiene. El programa declara char *cad[N] como array de punteros a char,
de tal forma que en la función entrada( ) se reserva memoria, con malloc( ), para cada
línea de texto.

13
Asignación Dinámica 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];
//Función 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) ;
}

//Función para leer N cadenas de caracteres


void entrada(char *cd[ ])
{
char B[121];
int j, tam;
printf("\tEscribe %d lineas de texto\n",N);
for(j=0; j<N; j++)
{
printf("Cadena[%d]: ",j+1);
gets(B) ;
tam = (strlen(B)+1)*sizeof(char);
cd[j] = (char *)malloc(tam) ;
strcpy(cd[j],B);
}
}

14
Asignación Dinámica de Memoria en C

//Función que cuenta el número de vocales que hay en una cadena


int vocales (char *c)
{
int k, j;
for (j=k=0; j<strlen(c); j++)
//Cuenta vocales de la cadena c
switch (tolower(*(c+j)))
{
case 'a' :
case 'e':
case 'i' :
case 'o':
case 'u':
k++;
break;
}
return k;
}

//Función para imprimir el número de vocales que tiene cada cadena


void salida(char *cd[],int *v)
{

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
Asignación Dinámica de Memoria en C

Ejemplo de Salida:

8.7 PUNTEROS A ESTRUCTURAS

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 “->”.

El hecho de declarar un puntero a una estructura no significa que dispongamos de la


estructura; es necesario asignar al puntero un bloque de memoria del tamaño de la
estructura donde se almacenarán los datos de la misma.

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
Asignación Dinámica 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);

printf("\n****Datos del Deportista****\n");


printf("Nombre: %s\n",dep->nombre);
printf("Peso: %.2f libras\n",dep->peso);
printf("Altura: %.2f mts\n",dep->altura);
}

Ejemplo de Salida:

Ejemplo #9: Este programa asigna memoria dinámica para un array de 3 estructuras
de tipo Estudiante y calcula cuál 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
Asignación Dinámica de Memoria en C

void main()
{
struct Estudiante *est;
int i=1,j=1,pos,may;

//Asignación de memoria para el array de 3 struct Estudiante


est = (struct Estudiante *)calloc(3,sizeof(struct Estudiante));
if(est==NULL)
{
printf("Insuficiente Espacio de Memoria\n");
exit(-1);
}
else
{
for(i=0;i<3;i++)
{
printf("Nombre Estudiante[%d]: ",i+1);
gets(est[i].nombre);
printf("Nota Estudiante[%d]: ",i+1);
scanf("%d",&est[i].nota);
fflush(stdin);
}
}
may=0;
for(j=0;j<3;j++)
{
if(est[j].nota > may)
{
may = est[j].nota;
pos = j;
}
}
printf("\n%s ES QUIEN OBTUVO LA MAYOR NOTA:%d\n\n",est[pos].nombre,may);
//Liberando la memoria asignada al puntero a struct (struct *est)
free(est);
}

18
Asignación Dinámica de Memoria en C

Ejemplo de Salida:

Ejemplo #10: El profesor de la asignatura de Practicas Profesionales desea conocer el


porcentaje de:
 Alumnos de Sexo Femenino y Masculino.
 Aprobados y reprobados, tomando en cuenta que la nota mínima para aprobar
es 60 pts.
//porcentaje.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Estudiante
{
char nombre[30];
char sexo;
int nota;
};
void main()
{
struct Estudiante *est;
int n,nest,ap=0,re=0,nef=0,nem=0;
float pap,prep,pf,pm;

printf("Introduzca el numero de estudiantes: ");


scanf("%d",&nest);
//Asignando Memoria para el array de N datos de tipo struct
est = (struct Estudiante *)calloc(nest,sizeof(struct Estudiante));
if(est==NULL)
{
printf("Insuficiente Espacio de Memoria\n");
exit(-1);
}

19
Asignación Dinámica 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);

if(est[n].nota >=0 && est[n].nota<=60)


ap++;
else
re++;
}
}
pap = (ap*100)/nest;
prep = (re*100)/nest;
pf=(nef*100)/nest;
pm=(nem*100)/nest;
printf("Hay %d estudiantes APROBADOS y representan %.2f%%\n",ap,pap);
printf("Hay %d estudiantes REPROBADOS y representan %.2f%%\n",re,prep);
printf("Hay %d alumnos de sexo FEMENINO y representan %.2f%%\n",nef,pf);
printf("Hay %d alumnos de sexo MASCULINO y representan %.2f%%\n",nem,pm);
//Liberando Memoria para est (struct Estudiante *est)
free(est);
}

20
Asignación Dinámica de Memoria en C

Ejemplo de Salida:

8.8 REGLAS DE FUNCIONAMIENTO DE LA ASlGNAClÓN DE MEMORIA

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:

1. El prototipo de las funciones esta en stdlib.h.


Ejemplo:
#include <stdlib.h>
int *datos;
datos = (int*)malloc(sizeof(int));

2. Las funciones malloc( ) , calloc() , realloc( ) devuelven el tipo void *, lo cual exige
hacer una conversión al tipo del puntero.

3. Las funciones de asignación tienen como argumento el número de bytes a reservar.

4. El operador sizeof permite calcular el tamaño de un tipo de objeto para el que está
asignando memoria.

21
Asignación Dinámica de Memoria en C

Ejemplo:
struct punto
{
float x,y,z;
}
struct punto *p = (struct punto *)malloc (sizeof(struct punto));

5. La función realloc( ) permite expandir memoria reservada.


Ejemplo:
#include <stdlib.h>
int *v=NULL;
int n;
scanf ("%d",&n) ;
v = (int*)realloc(v,n);
v = (int*)realloc(v,2*n);

6. Las funciones de asignación de memoria devuelven NULL si no han podido reservar la


memoria requerida.
Ejemplo:
double *v;
v = malloc(1000 * sizeof(double));
if (v == NULL)
{
puts ("Error de asignación de memoria. " ) ;
exit(-1);
}

7. Se puede utilizar cualquier función de asignación de memoria para reservar espacio


de objetos más complejos, tales como estructuras, arrays, en el almacenamiento libre.
Ejemplo:
#include <stdlib.h>
struct complejo
{
float x,y;
};

void main()
{
struct complejo *pz;
int n;

22
Asignación Dinámica 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 asignación de memoria.") ;
exit(-1);
}
}

8. Se pueden crear arrays multidimensionales de objetos con las funciones de asignación


de memoria. Para un array bidimensional n x m, se asigna en primer lugar memoria para un
array de punteros (de n elementos), y después se asigna memoria para cada fila (m
elementos) con un bucle desde 0 a n -1.
Ejemplo:
#include <stdlib.h>
double **mat;
int n,m,i;
mat = (double**)malloc(n*sizeof(double*)); /*array de punteros*/
for (i=0; i<n; i++)
{
mat[i] = (double *)malloc (m * sizeof(double)); /*fila de m elementos*/
}

9. Toda memoria reservada con alguna de las funciones de asignación de memoria se


puede liberar con la función free ( ).
Ejemplo: Para liberar la memoria de la matriz dinámica mat:
double **mat;
for (i=O; i<n; i++)
{
free(mat[i]) ;
}

23

También podría gustarte