En los programas descritos en los capítulos anteriores, todos los requisitos de memoria se determinaron antes de ejecutar el programa mediante la definición de las variables necesarias. Sin embargo, puede ocurrir que los requisitos de memoria de un programa sólo puedan determinarse durante la ejecución. Por ejemplo, cuando la memoria requerida depende de las entradas del usuario. En estos casos, los programas deben asignar dinámicamente la memoria, para la cual el lenguaje C++ integra los operadores nuevos y borrados.
Nuevos y nuevos operadores []
La memoria dinámica se asigna con el nuevo operador. new va seguida de un especificador de tipo de datos y, si se requiere una secuencia de varios elementos, su número entre paréntesis []. Devuelve un puntero al inicio del nuevo bloque de memoria asignado. Su sintaxis es la siguiente:
puntero = nuevo tip
o
puntero = nuevo tipo[number_elements]
La primera expresión se utiliza para asignar memoria a un único elemento tipo. El segundo se utiliza para asignar un bloque (una matriz) de elementos tipo, donde number_elements es un entero que representa la cantidad de estos elementos. Por ejemplo:
int * foo;toto = new int[5];
En este caso, el sistema asigna dinámicamente el espacio para cinco elementos int y devuelve un puntero al primer elemento de la secuencia, que se asigna a foo (un puntero. Por lo tanto, foo ahora apunta a un bloque de memoria válido con un espacio para cinco elementos int.
Aquí, foo es un puntero y el primer elemento designado por foo es accesible con la expresión foo[0] o la expresión * foo (ambas son equivalentes. El segundo elemento es accesible con foo[1] o * (foo + 1), etc.
Hay una diferencia sustancial entre la declaración de un arreglo normal y la asignación de memoria dinámica para un bloque de memoria que utiliza nuevo. La diferencia más importante es que el tamaño de un arreglo regular debe ser una expresión constante. Por lo tanto, su tamaño debe determinarse en el momento del diseño del programa, antes de la ejecución, mientras que la asignación de memoria dinámica realizada por new permite: asignar memoria durante la ejecución utilizando un valor de variable como tamaño.
La memoria dinámica solicitada por nuestro programa es asignada por el sistema desde el segmento de memoria. Sin embargo, la memoria de la computadora es un recurso limitado que puede ser agotado. Por lo tanto, no hay garantía de que todas las solicitudes de asignación de memoria que utilicen el nuevo operador sean aceptadas por el sistema.
C++ proporciona dos mecanismos estándar para comprobar si la asignación ha tenido éxito:
Una es gestionar las excepciones. Usando este método, se lanza una excepción bad_alloc cuando la asignación falla. Las excepciones son una poderosa característica de C++ que se explica más adelante en estos tutoriales. Pero por ahora, debe saber que si esta excepción es levantada y no es manejada por un administrador específico, la ejecución del programa está completa.
También leaLas clases en C++++Este
método de excepción es el método por defecto usado por los nuevos y es el que se usa en una declaración como:
toto = new int[5]; // si la asignación falla, se lanza una excepción
El otro método se conoce como nothrow y, cuando se utiliza, cuando falla una asignación de memoria, en lugar de lanzar una excepción bad_alloc o terminar el programa, el puntero devuelto por new es un puntero nulo y el programa continúa ejecutándose normalmente.
Este método puede ser especificado usando un objeto especial llamado nothrow, declarado en el encabezado
foo = new (nothrow) int[5];
En este caso, si la asignación de este bloque de memoria falla, puede detectarlo comprobando si foo es un puntero nulo:
int * foo;foo = new (nothrow) int[5];if (foo == nullptr) { // error when allocating memory.
Actúa. }
Es probable que este método de»nothrow» produzca un código menos eficiente que las excepciones, ya que implica comprobar explícitamente el valor del puntero devuelto después de cada asignación. Por lo tanto, se prefiere generalmente el mecanismo de excepción, al menos para las asignaciones críticas. Sin embargo, la mayoría de los ejemplos futuros utilizarán el mecanismo Nothrow debido a su simplicidad.
Borrar y borrar operadores []
En la mayoría de los casos, la memoria asignada dinámicamente sólo es necesaria para períodos de tiempo específicos en un programa; una vez que ya no la necesite, puede liberarla para que la memoria vuelva a estar disponible para otras solicitudes de memoria dinámica. Este es el objeto del operador de borrado cuya sintaxis es la siguiente:
borrar puntero;borrar puntero [];
La primera instrucción libera la memoria de un único elemento asignado usando nuevo, y la segunda libera la memoria asignada para conjuntos de elementos usando nuevo y un tamaño entre paréntesis ([].
El valor transmitido como argumento a borrar debe ser un puntero a un bloque de memoria previamente asignado con nuevo, o un puntero nulo (en el caso de un puntero nulo, el borrado no tiene efecto.
#include <iostream>#include <new>using namespace std;int main (){ int i, n; int * p; cost <<< "¿Cuántos números le gustaría escribir?
«
cin >> i; p = nuevo int[i]; si (p == nullptr) coste <<< "Error: no se ha podido asignar la memoria"; si no {para (n = 0; n <i; n ++) { coste <<<<< "Introducir número:
«
cin >> p[n]; } coste <<< "Usted ha introducido:"; para (n = 0; n <i; n ++) coste <<< p[n] <<","; suprimir [] p; } devolver 0;}
Resultado de la ejecución:
¿Cuántos números le gustaría escribir? 5Introduzca el número: 75Introduzca el número: 436Introduzca el número: 1067Introduzca el número: 8Introduzca el número: 32Introduzca el número: 75, 436, 1067, 8, 32,
Tenga en cuenta que el valor entre corchetes en la nueva instrucción es un valor de variable introducido por el usuario (i) y no una expresión constante:
p = nuevo (norow) int[i];
Siempre es posible que el usuario introduzca un valor para i tan grande que el sistema no pueda asignarle suficiente memoria. Por ejemplo, cuando intenté dar un valor de 1.000 millones a la pregunta «Cuántos dígitos», mi sistema no pudo asignar tanta memoria para el programa y recibí el mensaje de texto que habíamos preparado para este caso (Error: la memoria no se pudo asignar.
También readInstructions y flujos de controlSe
considera una buena práctica que los programas sean siempre capaces de gestionar los fallos de asignación de memoria, ya sea comprobando el valor del puntero o interceptando la excepción apropiada
.
Memoria dinámica en C
C ++ integra los operadores nuevos y los de borrado para la asignación de memoria dinámica. Pero no estaban disponibles en el lenguaje C, sino que utilizaba una solución de librería, con las funciones malloc, calloc, realloc y free, definidas en la cabecera
Tenga en cuenta, sin embargo, que los bloques de memoria asignados por estas funciones no son necesariamente compatibles con los devueltos por los nuevos, por lo que no deben mezclarse; cada uno debe procesarse con su propio conjunto de funciones u operadores.
Otros consejos interesantes:
- ¿Cómo instalar una memoria RAM? Guía para instalar una tira de memoria en un PC Instalar la memoria RAM es muy fácil, pero hay detalles importantes que conocer y errores que evitar. Aprenda a instalar correctamente una memoria RAM……
- Estructuras de datos en C++ Una estructura de datos es un grupo de elementos de datos agrupados bajo el mismo nombre. Estos elementos de datos, llamados miembros, pueden tener diferentes tipos y longitudes. Se pueden declarar las estructuras de datos……
- ¿Cómo borrar la memoria CMOS para restablecer la configuración de la BIOS? A veces podemos encontrar que nuestro ordenador sufre de problemas de hardware que no entendemos y no sabemos cómo resolverlos. Una posible solución a estos problemas podría ser restablecer el…
- Cómo crear un eje de tiempo de una tabla pivotante en Excel 2013 Si está cansado de manipular las fechas en su tabla pivotante utilizando herramientas de filtrado torpes, Microsoft finalmente ha proporcionado una mejor manera.
- El compilador en C++ Las herramientas esenciales necesarias para seguir estos tutoriales son un ordenador y una cadena de compilación para compilar el código C++ y construir los programas para ejecutarse. C ++ es un idioma……