Sei sulla pagina 1di 6

Conferencia # 2 Asignacin dinmica de memoria en C/C++ y excepciones

Sumario:
- Asignacin dinmica de memoria.
o Sintaxis de C, funcin malloc.
o Sintaxis de C++, operador new.
- Introduccin bsica a las excepciones.
Bibliografa
Texto: Como programar en C++, Tomo II pg 470-471.
Texto: Como programar en C++, Tomo II pg 576-579.
Objetivos:
Que el estudiante conozca el concepto de memoria dinmica y lo aplique utilizando la
sintaxis de los lenguajes C y C++.
Que el estudiante conozca los operadores de manejo de excepciones try catch y los utilice
para gestionar el proceso de peticin de memoria dinmica.
Introduccin
La asignacin de la memoria para las variables no es responsabilidad del programador.
La memoria de las variables estticas y globales (cuando comienza el programa),
Las variables locales, se les asigna la memoria, pero cuando comienza a ejecutarse el
bloque en la que estn definidas.
Problemas:
- La memoria asignada a los programas puede ser insuficiente en aplicaciones
complejas.
- No se puede cambiar el tamao de los arreglos una vez creados.
- El tamao de los arreglos debe ser creado usando una constante.
Solucin:
- Asignacin dinmica de la memoria.
Desarrollo
1. Asignacin dinmica de memoria.
A estos pedidos de memoria que realiza el programador es a lo que llamaremos asignacin
dinmica de memoria.

Conf # 2 Pg 1 de 6

Pedir memoria dinmicamente lo haremos mediante el llamado a una funcin de biblioteca


o usando un operador (malloc, new). Si existe esa cantidad de memoria libre, la funcin
u operador que asigna la memoria nos devolver la direccin donde comienza la memoria
que nos ha sido asignada. Todos los bytes estarn de forma consecutiva formando un
bloque (como en un arreglo de bytes ).
La direccion de inicio de ese bloque de memoria que se asigna dinmicamente, debemos
copiarlo en un puntero para poder utilizarlo posteriormente. Cuando queramos devolver la
memoria solicitada, tambin lo haremos con otra funcin de biblioteca u operador a la que
le pasaremos la direccin inicial de la memoria que nos fue asignada previamente
(mediante un puntero ).
Para la devolucin de la memoria dinmica tenemos la funcin free o delete.
1.1. El operador new y la funcin malloc.
Consideremos un tipo T previamente definido. T puede ser cualquier tipo de datos
predefinido del lenguaje C/C++ o cualquiera de los tipos de datos que hemos definido hasta
el momento.
Para crear una variable dinmica de tipo T y obtener su direccin en un puntero que
llamaremos ptr, podemos programar las siguientes instrucciones:
En C++
T *ptr ;
ptr = new T ;

En C y C++
#include <alloc.h>
typedef unsigned size_t
void* malloc(size_t size);
T *ptr ;
ptr = (T*)malloc(sizeof(T));

Si existe suficiente memoria, una vez que se ejecute esta ltima instruccin, en la variable
ptr se copiar la direccin de la variable de tipo T, esquemticamente tendremos:

Observaciones:
no poseen un identificador propio, tendremos que referirnos a travs de un puntero que
contenga su direccin.
El caso de malloc debe hacerse un cast al tipo adecuado, debido a que malloc devuelve
*void.
Utilizareemos el operador de indireccin aplicado al puntero, es decir *ptr.
Utilizando el operador de acceso a elemento de arreglo, o sea, con ptr[0].
Valor inicial (Solo con new) :
o ptr = new T ( To);

Conf # 2 Pg 2 de 6

En este caso tendremos que al crearse la variable dinmica ser inicializada con el valor To,
por lo que el contenido de lo apuntado por ptr ser el valor To, o sea:
Observe que con una instruccin como
T *ptr = new T (To) ;

<=>

T* ptr = new T ;
*ptr = To;

1.2. El operador delete y funcin free.


Para devolver la memoria previamente asignada con new a una variable dinmica, si la
direccin de esta variable est en un puntero que hemos llamado ptr, entonces lo haremos
ejecutando una instruccin como la siguiente:
delete ptr;
free(ptr);
1.3. Errores de asignacin dinmica de memoria.
No siempre la memoria dinmica que se pide estar disponible. (Heap reservado al
comienzo del programa)
En Windows, los programas utilizan, adems, un heap global cuando el pedido de
memoria es lo suficientemente grande
Devolucin de NULL segn compiladores en error de asignacin.
As, un segmento de programa que crea una variable dinmica entera y posteriormente le
asigna el valor 4 se escribira de la siguiente forma:
C++

C y C++

int *ptr1 = new int ;


if ( ptr1 )
*ptr1 = 4;
else
printf(Error de asignacin dinmica\n)

int *ptr1 = malloc(sizeof(int)) ;


if ( ptr1 )
*ptr1 = 4;
else
printf(Error de asignacin dinmica\n)

1.4. Las variables dinmicas y el operador de asignacin predefinido.


Cuando trabajamos con variables dinmicas es muy importante establecer la diferencia que
existe entre una asignacin de punteros y la asignacin de las variables dinmicas
apuntadas por punteros.
Si tenemos las siguientes instrucciones
int *ptr1 = new int( 4 );

Conf # 2 Pg 3 de 6

int *ptr2 = new int( 5 );


int *ptr1 = malloc(sizeof(int)) ;
*ptr1 = 4;
int *ptr2 = malloc(sizeof(int)) ;
ptr2 = 5;

Debajo se muestra lo que ocurre si ejecutamos una asignacin de punteros o una asignacin
de lo apuntado por el puntero:

ptr1 = ptr2

*ptr1 = *ptr2 / ptr1[0]

= ptr2[0]

Lo correcto sera:
delete ptr1;
ptr1 = ptr2;
Free(ptr1);
ptr1 = ptr2;

1.5 Asignacin dinmica de memoria para arreglos. Operadores new[] y delete []


Si T es un tipo de datos predefinido, o como los que hemos definido hasta el momento,
entonces, podemos crear un arreglo dinmico de elementos de tipo T con la expresin
new T [N], donde N es una variable, expresin o constante entera que indica la cantidad
mxima de elementos que puede contener el arreglo.
El valor que devuelve esta expresin es un puntero al primer elemento del arreglo, por lo
que debe ser asignado a un puntero al tipo de datos T.
Para destruir un arreglo dinmico que fue creado mediante un llamado anterior al
operador new[], es necesario aplicar el operador delete[] a una variable puntero que
contenga la direccin del primer elemento del arreglo. Una vez que se destruya una
variable dinmica, no se puede hacer referencia a ella. De hacerlo, provocaramos un
error de ejecucin en el programa.

Conf # 2 Pg 4 de 6

Ejemplo:
#include <iostream.h>
#include <conio.h>
#include <alloc.h>
void main(void){
unsigned short int n;
int *ptr;
int *ptr1;
printf("Deme la cantidad de elementos del arreglo a crearse: ");
scanf(%d, &n);
ptr=new int[n];
// ptr = (int *)malloc(5*sizeof(int));
ptr1=ptr;
if(ptr == NULL)
{
printf("No se pudo reservar memoria ");
exit(0);
}
for (int i=0;i<n;i++)
{
printf( "\nValor de elemento %d:",i);
scanf(%d, & ptr[i];);
}
float prom=0;
for (int i=0;i<n;i++,ptr1++)
prom+=(float) *ptr1/n;
printf ( "El promedio es: %f",prom);
printf ( \n sizeof(ptr) es: %d, sizeof(ptr));
getch();
delete [] ptr;
// free(ptr)
}

Conf # 2 Pg 5 de 6

1.6. Excepciones.
Las excepciones son situaciones anormales que requieren un tratamiento especial,
tienen por qu ser errores.

no

Funcionamiento:

Existe una funcin A que invoca a otra funcin B.


La funcin B se encuentra en una situacin que puede considerarse como
excepcional y lanza una excepcin.
En este momento termina la ejecucin de la funcin B, y si la excepcin no es
capturada dentro de A, entonces A retorna inmediatamente a la funcin que la
invoc.
La funcin A puede capturar la excepcin y tratarla, parte del tratamiento de la
excepcin puede ser volver a lanzarla.
Si la funcin A no captura la excepcin, alguna de las funciones que ha llamado
directa o indirectamente a A debe hacerlo, de lo contrario se detiene la ejecucin del
programa debido a que no se ha encontrado un manejador para esta excepcin.

Mecanismo formado por tres partes:


1. Captura de excepciones.
Bloque try{}
2. Tratamiento de excepciones. Bloque catch(){}
3. Lanzamiento de excepciones. Operador throw
Ejemplo Tratamiento y Captura
int *ptr1 ;
try {
ptr1 = new int ;
// ptr1 = (int*)malloc(sizeof(int));
*ptr1 = 4;
// tambin podemos poner ptr1 = new int(4);
}
catch( std::bad_alloc ) {
printf(Error de asignacin dinmica\n);
}

OJO: Ptr1 no puede ser local al bloque try.

Ejercicios propuestos para el Estudio Independiente


Texto pg 591: Ejercicios 15.17 al 15.18, 15.21 e) y k)

Conf # 2 Pg 6 de 6

Potrebbero piacerti anche