13.01.2015 Views

Pensar en C++ (Volumen 1) - Grupo ARCO

Pensar en C++ (Volumen 1) - Grupo ARCO

Pensar en C++ (Volumen 1) - Grupo ARCO

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

✐<br />

✐<br />

✐<br />

“Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 395 — #433<br />

✐<br />

13.3. new y delete para vectores<br />

al compilador que la función puede disparar una excepción del tipo indicado. En segundo<br />

lugar, si efectivam<strong>en</strong>te se agota la memoria, la función alcanzará la s<strong>en</strong>t<strong>en</strong>cia<br />

throw bad_alloc() lanzando la excepción. En el caso de que esto ocurra, la función<br />

deja de ejecutarse y se cede el control del programa a la rutina de tratami<strong>en</strong>to<br />

de excepción que se ha definido <strong>en</strong> una cláusula catch(bad_alloc).<br />

En main() se puede ver la cláusula try-catch que es la otra parte del mecanismo.<br />

El código que puede lanzar la excepción queda d<strong>en</strong>tro del bloque try; <strong>en</strong> este caso,<br />

llamadas a new para objetos Framis. Justo a continuación de dicho bloque sigue<br />

una o varias cláusulas catch, especificando <strong>en</strong> cada una la excepción a la que se<br />

destina. En este caso, catch(bad_alloc) indica que <strong>en</strong> ese bloque se tratarán las<br />

excepciones de tipo bad_alloc. El código de este bloque sólo se ejecutará si se dispara<br />

la excepción, continuando la ejecución del programa justo después de la última del<br />

grupo de cláusulas catch que existan. Aquí sólo hay una, pero podría haber más.<br />

En este ejemplo, el uso de iostream es correcto ya que el operator new()<br />

global no ha sido modificado.<br />

El operator delete() asume que la dirección de Framis ha sido obt<strong>en</strong>ida<br />

de nuestro almacén particular. Una asunción justa, ya que cada vez que se crea un<br />

objeto Framis simple se llama al operator new() local; pero cuando se crea un<br />

vector de tales objetos se llama al new global. Esto causaría problemas si el usuario<br />

llamara accid<strong>en</strong>talm<strong>en</strong>te al operador delete sin usar la sintaxis para destrucción de<br />

vectores. Podría ser que incluso estuviera tratando de borrar un puntero a un objeto<br />

de la pila. Si cree que estas cosas puedan suceder, convi<strong>en</strong>e p<strong>en</strong>sar <strong>en</strong> añadir una<br />

línea que asegurare que la dirección está <strong>en</strong> el intervalo correcto (aquí se demuestra<br />

el pot<strong>en</strong>cial que ti<strong>en</strong>e la sobrecarga de los operadores new y delete para la localización<br />

de fugas de memoria).<br />

operador delete() calcula el bloque al que el puntero repres<strong>en</strong>ta y después<br />

pone a false la bandera correspondi<strong>en</strong>te <strong>en</strong> el mapa de localización, para indicar<br />

que dicho bloque está libre.<br />

En la función main(), se crean dinámicam<strong>en</strong>te sufici<strong>en</strong>tes objetos Framis para<br />

agotar la memoria. Con esto se prueba el comportami<strong>en</strong>to del programa <strong>en</strong> este caso.<br />

A continuación, se libera uno de los objetos y se crea otro para mostrar la reutilización<br />

del bloque recién liberado.<br />

Este esquema específico de asignación de memoria es probablem<strong>en</strong>te mucho más<br />

rápido que el esquema de propósito g<strong>en</strong>eral que usan los operadores new y delete<br />

originales. Se debe advertir, no obstante, que este <strong>en</strong>foque no es automáticam<strong>en</strong>te<br />

utilizable cuando se usa her<strong>en</strong>cia, un tema que verá <strong>en</strong> el Capítulo 14 (FIXME).<br />

Sobrecarga de new y delete para vectores<br />

Si se sobrecargan los operadores new y delete para una clase, esos operadores<br />

se llaman cada vez que se crea un objeto simple de esa clase. Sin embargo, al crear<br />

un vector de tales objetos se llama al operator new() global para obt<strong>en</strong>er el espacio<br />

necesario para el vector, y al operator delete() global para liberarlo. Es<br />

posible controlar también la asignación de memoria para vectores sobrecargando los<br />

métodos operator new[] y operator delete[]; se trata de versiones especiales<br />

para vectores. A continuación se expone un ejemplo que muestra el uso de ambas<br />

versiones.<br />

//: C13:ArrayOperatorNew.cpp<br />

// Operator new for arrays<br />

#include // Size_t definition<br />

395<br />

✐<br />

✐<br />

✐<br />

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!