¿No sabes por dónde empezar? Ayúdanos normalizando artículos.
¿Tienes experiencia? Crea alguno de estos artículos de actualidad.

Diferencia entre revisiones de «Operador new con matrices»

Línea 1: Línea 1:
{{Normalizar}}<div align="justify">{{Definición|Nombre=Operador new con matrices|imagen=  |concepto=El Estándar C++ establece cuatro nuevos operadores para crear y destruir objetos persistentes. new, delete, new [ ] y delete [ ]. Los dos primeros se utilizan para objetos de cualquier tipo. Por su parte new [] y delete [] se utilizan para crear y destruir matrices}}'''Operador new con matrices'''. Proporciona espacio de almacenamiento persistente, similar pero superior a la función de Librería Estándar malloc. Este operador permite crear un objeto de cualquier tipo, incluyendo tipos definidos por el usuario, y devuelve un puntero (del tipo adecuado) al objeto creado. Su utilización exige que el usuario declarare un puntero del tipo adecuado; a continuación debe ser inicializado con el valor devuelto por el operador.  
+
{{Definición|Nombre=Operador new con matrices|imagen=  |concepto=El Estándar C++ establece cuatro nuevos operadores para crear y destruir objetos persistentes. new, delete, new [ ] y delete [ ]. Los dos primeros se utilizan para objetos de cualquier tipo. Por su parte new [] y delete [] se utilizan para crear y destruir matrices}}
Casi todo lo dicho respecto a new, incluyendo sus precauciones y limitaciones, es también de aplicación a su contrapartida new[] para matrices, de modo que este último, más que un operador independiente, puede considerarse como una versión del primero con el modificador [ ]
+
<div align="justify">
El operador new[ ] permite crear matrices de objetos de cualquier tipo en el montón, incluyendo tipos definidos por el usuario, y devuelve un puntero al primer elemento de la matriz creada
+
 
Su utilización exige que el usuario declarare un puntero del tipo adecuado; a continuación este puntero debe ser inicializado con el valor devuelto por el operador. Si el objeto creado es tipo T, sería algo así (más detalles a continuación ):
+
'''Operador new con matrices'''. Proporciona espacio de almacenamiento persistente, similar pero superior a la función de Librería Estándar malloc. Este operador permite crear un objeto de cualquier tipo, incluyendo tipos definidos por el usuario, y devuelve un puntero (del tipo adecuado) al objeto creado. Su utilización exige que el usuario declarare un puntero del tipo adecuado; a continuación debe ser inicializado con el valor devuelto por el operador. Casi todo lo dicho respecto a new, incluyendo sus precauciones y limitaciones, es también de aplicación a su contrapartida new[] para matrices, de modo que este último, más que un operador independiente, puede considerarse como una versión del primero con el modificador.
 +
Permite crear matrices de objetos de cualquier tipo en el montón, incluyendo tipos definidos por el usuario, y devuelve un puntero al primer elemento de la matriz creada. Su utilización exige que el usuario declarare un puntero del tipo adecuado; a continuación este puntero debe ser inicializado con el valor devuelto por el operador. Si el objeto creado es tipo T, sería algo así (más detalles a continuación ):
 
T* puntero = valor-devuelto-por-new[];
 
T* puntero = valor-devuelto-por-new[];
 +
 
== Sintaxis ==
 
== Sintaxis ==
 
La sintaxis para crear una matriz de objetos tipo tipoX es:
 
La sintaxis para crear una matriz de objetos tipo tipoX es:
Línea 11: Línea 13:
 
El argumento <tipoX> es imprecindible. Indica el tipo de objeto que se guardará en la matriz. Por ejemplo int, long, char, UnaClase, etc. Si la especificación de tipoX es complicada, se permite englobarla en paréntesis para facilitar al compilador la correcta interpretación (segunda forma de la sintaxis). Ejemplo:
 
El argumento <tipoX> es imprecindible. Indica el tipo de objeto que se guardará en la matriz. Por ejemplo int, long, char, UnaClase, etc. Si la especificación de tipoX es complicada, se permite englobarla en paréntesis para facilitar al compilador la correcta interpretación (segunda forma de la sintaxis). Ejemplo:
 
int* imptr = new int[3];  // crear matriz de 3 enteros
 
int* imptr = new int[3];  // crear matriz de 3 enteros
  <dimension> este argumento opcional indica la dimensión de la matriz.
+
<dimension> este argumento opcional indica la dimensión de la matriz.
  <::>  argumento opcional que invoca la versión global de new[]. Este argumento se utiliza cuando existe una versión específica de usuario (sobrecargada) pero se desea utilizar la versión global.
+
<::>  argumento opcional que invoca la versión global de new[]. Este argumento se utiliza cuando existe una versión específica de usuario (sobrecargada) pero se desea utilizar la versión global.
 
<situación>, este especificador opcional proporciona argumentos adicionales a new. Puede utilizarse solamente si se tiene una versión sobrecargada de new que coincida con estos argumentos opcionales. Esta opción se ha previsto para aquellos casos en que el usuario desea poder definir el sitio concreto en que se realizará la reserva de memoria.
 
<situación>, este especificador opcional proporciona argumentos adicionales a new. Puede utilizarse solamente si se tiene una versión sobrecargada de new que coincida con estos argumentos opcionales. Esta opción se ha previsto para aquellos casos en que el usuario desea poder definir el sitio concreto en que se realizará la reserva de memoria.
 
  Como puede verse, el operador new [ ] para matrices no admite un iniciador como el operador new genérico, de forma que cuando se crea una matriz de objetos de tipo abstracto, se utiliza siempre el constructor por defecto de la clase para iniciar cada uno de los objetos de la matriz. Recordar que los objetos creados con new deben ser destruidos necesariamente con delete, y que las matrices creadas con new[] deben ser borradas con delete[].
 
  Como puede verse, el operador new [ ] para matrices no admite un iniciador como el operador new genérico, de forma que cuando se crea una matriz de objetos de tipo abstracto, se utiliza siempre el constructor por defecto de la clase para iniciar cada uno de los objetos de la matriz. Recordar que los objetos creados con new deben ser destruidos necesariamente con delete, y que las matrices creadas con new[] deben ser borradas con delete[].
 +
 
Nota: en el caso de matrices de tipos básicos (predefinidos en el lenguaje) siempre es posible iniciar el espacio correspondiente con la función memset de la librería C++ clásica.
 
Nota: en el caso de matrices de tipos básicos (predefinidos en el lenguaje) siempre es posible iniciar el espacio correspondiente con la función memset de la librería C++ clásica.
 +
 
== Descripción ==
 
== Descripción ==
 
Una expresión del tipo:
 
Una expresión del tipo:
Línea 24: Línea 28:
 
Cuando se crean matrices multidimensionales con new, deben proporcionarse todas las dimensiones, aunque la primera dimensión no tiene porqué ser una constante (de tiempo de compilación), las siguientes sí  
 
Cuando se crean matrices multidimensionales con new, deben proporcionarse todas las dimensiones, aunque la primera dimensión no tiene porqué ser una constante (de tiempo de compilación), las siguientes sí  
 
void func() {
 
void func() {
  int* pt1[];                  // L.2 Ilegal
+
int* pt1[];                  // L.2 Ilegal
  extern int* pt2[];          // L.3: Ok.
+
extern int* pt2[];          // L.3: Ok.
  int* pt3[3];                // L.4: Ok. correcto
+
int* pt3[3];                // L.4: Ok. correcto
  ...
+
...
  pt5 = new int[3][10][12];    // L.5: Ok. correcto
+
pt5 = new int[3][10][12];    // L.5: Ok. correcto
  pt6 = new int[n][10][12];    // L.6: Ok. correcto
+
pt6 = new int[n][10][12];    // L.6: Ok. correcto
  pt7 = new int[3][][12];      // Ilegal
+
pt7 = new int[3][][12];      // Ilegal
  pt8 = new int[][10][12];    // Ilegal
+
pt8 = new int[][10][12];    // Ilegal
 
}
 
}
 
L.2 es ilegal porque no especifica el tamaño de la matriz, sin embargo L.3 es correcto (se indica al compilador que el resto de la información está en un módulo distinto. L.4 declara una matriz de tres elementos que son punteros-a-int.
 
L.2 es ilegal porque no especifica el tamaño de la matriz, sin embargo L.3 es correcto (se indica al compilador que el resto de la información está en un módulo distinto. L.4 declara una matriz de tres elementos que son punteros-a-int.
 
L.3 simplemente declara un objeto (existencia semántica);  L.4 declara el objeto y lo inicia (reserva espacio en memoria); en este caso en la pila, ya que es un objeto automático.
 
L.3 simplemente declara un objeto (existencia semántica);  L.4 declara el objeto y lo inicia (reserva espacio en memoria); en este caso en la pila, ya que es un objeto automático.
 
L.5 y L.6 crean matrices tridimensionales en el montón. Son objetos anónimos (que no tienen identificador), por lo que deben ser accedidos indirectamente. En este caso el acceso deberá realizarse a través de los punteros pt5 y pt6, que suponemos son objetos automáticos, y por tanto situados en la pila; además pt5 y pt6 deben ser de tipos adecuados para señalar a una matriz tridimensional de enteros (ver a continuación).
 
L.5 y L.6 crean matrices tridimensionales en el montón. Son objetos anónimos (que no tienen identificador), por lo que deben ser accedidos indirectamente. En este caso el acceso deberá realizarse a través de los punteros pt5 y pt6, que suponemos son objetos automáticos, y por tanto situados en la pila; además pt5 y pt6 deben ser de tipos adecuados para señalar a una matriz tridimensional de enteros (ver a continuación).
 +
 
== Asignar el valor devuelto ==
 
== Asignar el valor devuelto ==
 
La forma usual de utilizar el operador new[ ] es en sentencias de asignación. Puesto que new[] devuelve un puntero, es utilizado en el lado derecho (Rvalue) de la asignación. En el lado izquierdo (Lvalue) debe existir un puntero de tipo adecuado para recibir el valor devuelto. Preste atención a las declaraciones de punteros de los siguientes ejemplos:
 
La forma usual de utilizar el operador new[ ] es en sentencias de asignación. Puesto que new[] devuelve un puntero, es utilizado en el lado derecho (Rvalue) de la asignación. En el lado izquierdo (Lvalue) debe existir un puntero de tipo adecuado para recibir el valor devuelto. Preste atención a las declaraciones de punteros de los siguientes ejemplos:
Línea 49: Línea 54:
 
Las líneas 6, 8 y 10 compilan sin dificultad con Borland C++ 5.5, aunque producen error con Visual C++ 6.0 y Linux GCC v 2.95.3. En rigor los tipos de los punteros a la izquierda y derecha de la asignación no son iguales en estas líneas. Por ejemplo, en L.8 el tipo del Lvalue es int ( *)[ ][2], mientras que el Rvalue es int ( *)[10][2]. En estos casos es posible hacer un "casting" explícito para convertir el tipo de la derecha en el de la izquierda (es lo que hace Borland automáticamente).
 
Las líneas 6, 8 y 10 compilan sin dificultad con Borland C++ 5.5, aunque producen error con Visual C++ 6.0 y Linux GCC v 2.95.3. En rigor los tipos de los punteros a la izquierda y derecha de la asignación no son iguales en estas líneas. Por ejemplo, en L.8 el tipo del Lvalue es int ( *)[ ][2], mientras que el Rvalue es int ( *)[10][2]. En estos casos es posible hacer un "casting" explícito para convertir el tipo de la derecha en el de la izquierda (es lo que hace Borland automáticamente).
 
Observe que en L.4 el puntero a matriz de enteros de una dimensión int[3] se define como puntero-a-entero int*. Que en L.7, el puntero a matriz de enteros de dos dimensiones int[3][10] se define como puntero-a-matriz de enteros de una dimensión int ( *)[10]. Que en L.9 el puntero a matriz de tres dimensiones  int[3][10][2] se define como puntero a matriz de enteros de dos dimensiones int ( *)[10][2]; y a así sucesivamente.
 
Observe que en L.4 el puntero a matriz de enteros de una dimensión int[3] se define como puntero-a-entero int*. Que en L.7, el puntero a matriz de enteros de dos dimensiones int[3][10] se define como puntero-a-matriz de enteros de una dimensión int ( *)[10]. Que en L.9 el puntero a matriz de tres dimensiones  int[3][10][2] se define como puntero a matriz de enteros de dos dimensiones int ( *)[10][2]; y a así sucesivamente.
 +
 
==  Ejemplo ==
 
==  Ejemplo ==
 
El programa que sigue muestra el uso del operador new[] asignando espacio para una matriz bidimensional y de delete[ ] para desasignando después.
 
El programa que sigue muestra el uso del operador new[] asignando espacio para una matriz bidimensional y de delete[ ] para desasignando después.
Línea 59: Línea 65:
  
 
int main(void) {    // ==========
 
int main(void) {    // ==========
  double** data;                  // M1:
+
double** data;                  // M1:
  try {                            // Controlar excepciones
+
try {                            // Controlar excepciones
    data = new double* [fil];    // M3:
+
data = new double* [fil];    // M3:
    for (int j = 0; j < fil; j++)    //
+
for (int j = 0; j < fil; j++)    //
      data[j] = new double [col]; // Fase-2: Establecer columnas
+
data[j] = new double [col]; // Fase-2: Establecer columnas
  }
+
}
  catch (std::bad_alloc) {        // capturar posibles errores
+
catch (std::bad_alloc) {        // capturar posibles errores
    cout << "Imposible asignar espacio. Saliendo...";
+
cout << "Imposible asignar espacio. Saliendo...";
    exit(-1);                      // terminar con error
+
exit(-1);                      // terminar con error
  }
+
}
  for (int i = 0; i < fil; i++)  //
+
for (int i = 0; i < fil; i++)  //
    for (int j = 0; j < col; j++)
+
for (int j = 0; j < col; j++)
      data[i][j] = i + j;
+
data[i][j] = i + j;
  display(data);                  // mostrar datos
+
display(data);                  // mostrar datos
  borra(data);                    // borrar datos
+
borra(data);                    // borrar datos
  delete[] data;                  // A23: Borrar filas
+
delete[] data;                  // A23: Borrar filas
  return 0;                        // terminar Ok.
+
return 0;                        // terminar Ok.
 
}
 
}
 
void display(double **data) {    // Función auxiliar-1
 
void display(double **data) {    // Función auxiliar-1
  for (int i = 0; i < fil; i++) {
+
for (int i = 0; i < fil; i++) {
    for (int j = 0; j < col; j++)
+
for (int j = 0; j < col; j++)
      cout << data[i][j] << " ";
+
cout << data[i][j] << " ";
    cout << "\n";
+
cout << "\n";
  }
+
}
 
}
 
}
 
void borra(double **data) {      // Función auxiliar-2
 
void borra(double **data) {      // Función auxiliar-2
Línea 100: Línea 106:
 
El puntero data se inicia con el resultado de crear una matriz de fil elementos tipo double* (puntero-a-double). Justamente porque cada elemento de esta matriz contendrá un puntero a una matriz de doubles (cada una de las cuales es una columna).
 
El puntero data se inicia con el resultado de crear una matriz de fil elementos tipo double* (puntero-a-double). Justamente porque cada elemento de esta matriz contendrá un puntero a una matriz de doubles (cada una de las cuales es una columna).
 
</div>  
 
</div>  
 +
 
== Véase también  ==
 
== Véase también  ==
 
*[[Operadores|Operadores]]  
 
*[[Operadores|Operadores]]  
Línea 115: Línea 122:
 
*[[Operador de acceso a ámbito|Operador de acceso a ámbito]]
 
*[[Operador de acceso a ámbito|Operador de acceso a ámbito]]
 
*[[Operadores de puntero|Operadores de puntero]]
 
*[[Operadores de puntero|Operadores de puntero]]
 +
 
== Fuente  ==
 
== Fuente  ==
* [http://http://www.zator.com/Cpp/E4_9_20c.htm El operador new con matrices]
+
*Cambiando la forma de operar de new y delete [https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=17&ved=2ahUKEwiRtMXOl-PeAhWP1FkKHb0PDCw4ChAWMAZ6BAgEEAI&url=http%3A%2F%2Fwww.itlalaguna.edu.mx%2FAcademico%2FCarreras%2Fsistemas%2Fprogramacion2%2Fcpp8c.pdf&usg=AOvVaw1b-ASSdd5xdj72yl_iJHQc]. Consultado 20/11/2018
* [http://c.conclase.net/curso/?cap=013b Operador new en C.conclase.net]
+
*Diferencia entre Java y C++ [https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=26&ved=2ahUKEwjrtN-NmOPeAhWKwFkKHVqwBqk4FBAWMAV6BAgCEAI&url=http%3A%2F%2Fwww2.caminos.upm.es%2FDepartamentos%2Fmatematicas%2FFdistancia%2FPIE%2Fjava%2Ftemasj%2Ftjava5.pdf&usg=AOvVaw20n47eI70nKeDnFrDdegiq]. Consultado 20/11/2018
* [http://es.scribd.com/doc/52676357/57/Operadores-new-y-delete Operadores new y delete]
+
*Curso de programación en C++[https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=31&ved=2ahUKEwjv-_zKn-PeAhUL31MKHVGiDUQ4HhAWMAB6BAgJEAI&url=https%3A%2F%2Fwww.uv.es%2Fsto%2Fcursos%2Fc%2B%2B%2Fcurso95.pdf&usg=AOvVaw3twAc9_3V5DzjfXj6X-XVz]. Consultado 20/11/2018
 +
 
 
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Programación]]
 
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Programación]]

Revisión del 11:10 20 nov 2018

Operador new con matrices
Información sobre la plantilla
Concepto:El Estándar C++ establece cuatro nuevos operadores para crear y destruir objetos persistentes. new, delete, new [ ] y delete [ ]. Los dos primeros se utilizan para objetos de cualquier tipo. Por su parte new [] y delete [] se utilizan para crear y destruir matrices

Operador new con matrices. Proporciona espacio de almacenamiento persistente, similar pero superior a la función de Librería Estándar malloc. Este operador permite crear un objeto de cualquier tipo, incluyendo tipos definidos por el usuario, y devuelve un puntero (del tipo adecuado) al objeto creado. Su utilización exige que el usuario declarare un puntero del tipo adecuado; a continuación debe ser inicializado con el valor devuelto por el operador. Casi todo lo dicho respecto a new, incluyendo sus precauciones y limitaciones, es también de aplicación a su contrapartida new[] para matrices, de modo que este último, más que un operador independiente, puede considerarse como una versión del primero con el modificador. Permite crear matrices de objetos de cualquier tipo en el montón, incluyendo tipos definidos por el usuario, y devuelve un puntero al primer elemento de la matriz creada. Su utilización exige que el usuario declarare un puntero del tipo adecuado; a continuación este puntero debe ser inicializado con el valor devuelto por el operador. Si el objeto creado es tipo T, sería algo así (más detalles a continuación ): T* puntero = valor-devuelto-por-new[];

Sintaxis

La sintaxis para crear una matriz de objetos tipo tipoX es: <::> new <(situación)> <tipoX> [<dimension>]; <::> new <(situación)> (<tipoX>) [<dimension>];

El argumento <tipoX> es imprecindible. Indica el tipo de objeto que se guardará en la matriz. Por ejemplo int, long, char, UnaClase, etc. Si la especificación de tipoX es complicada, se permite englobarla en paréntesis para facilitar al compilador la correcta interpretación (segunda forma de la sintaxis). Ejemplo: int* imptr = new int[3]; // crear matriz de 3 enteros <dimension> este argumento opcional indica la dimensión de la matriz. <::> argumento opcional que invoca la versión global de new[]. Este argumento se utiliza cuando existe una versión específica de usuario (sobrecargada) pero se desea utilizar la versión global. <situación>, este especificador opcional proporciona argumentos adicionales a new. Puede utilizarse solamente si se tiene una versión sobrecargada de new que coincida con estos argumentos opcionales. Esta opción se ha previsto para aquellos casos en que el usuario desea poder definir el sitio concreto en que se realizará la reserva de memoria.

Como puede verse, el operador new [ ] para matrices no admite un iniciador como el operador new genérico, de forma que cuando se crea una matriz de objetos de tipo abstracto, se utiliza siempre el constructor por defecto de la clase para iniciar cada uno de los objetos de la matriz. Recordar que los objetos creados con new deben ser destruidos necesariamente con delete, y que las matrices creadas con new[] deben ser borradas con delete[].

Nota: en el caso de matrices de tipos básicos (predefinidos en el lenguaje) siempre es posible iniciar el espacio correspondiente con la función memset de la librería C++ clásica.

Descripción

Una expresión del tipo: tipoX* ptr = new tipoX [size] Reserva en el montón un espacio definido por sizeof(tipoX) * size + n; suficiente para alojar una matriz de size elementos de tipoX. El resultado del operador es un puntero que señala al primer elemento de la matriz. Nota: el valor n representa un espacio adicional que necesita el compilador para incluir información sobre las dimensiones de la matriz y sobre el tamaño reservado. Este valor es dependiente de la implementación, y puede variar de una invocación de new[] a otra. Por supuesto, todo este espacio es liberado cuando se utiliza el operador delete[] con el puntero correspondiente

Cuando se crean matrices multidimensionales con new, deben proporcionarse todas las dimensiones, aunque la primera dimensión no tiene porqué ser una constante (de tiempo de compilación), las siguientes sí void func() {

int* pt1[];                  // L.2 Ilegal

extern int* pt2[]; // L.3: Ok. int* pt3[3]; // L.4: Ok. correcto ... pt5 = new int[3][10][12]; // L.5: Ok. correcto pt6 = new int[n][10][12]; // L.6: Ok. correcto pt7 = new int[3][][12]; // Ilegal pt8 = new int[][10][12]; // Ilegal } L.2 es ilegal porque no especifica el tamaño de la matriz, sin embargo L.3 es correcto (se indica al compilador que el resto de la información está en un módulo distinto. L.4 declara una matriz de tres elementos que son punteros-a-int. L.3 simplemente declara un objeto (existencia semántica); L.4 declara el objeto y lo inicia (reserva espacio en memoria); en este caso en la pila, ya que es un objeto automático. L.5 y L.6 crean matrices tridimensionales en el montón. Son objetos anónimos (que no tienen identificador), por lo que deben ser accedidos indirectamente. En este caso el acceso deberá realizarse a través de los punteros pt5 y pt6, que suponemos son objetos automáticos, y por tanto situados en la pila; además pt5 y pt6 deben ser de tipos adecuados para señalar a una matriz tridimensional de enteros (ver a continuación).

Asignar el valor devuelto

La forma usual de utilizar el operador new[ ] es en sentencias de asignación. Puesto que new[] devuelve un puntero, es utilizado en el lado derecho (Rvalue) de la asignación. En el lado izquierdo (Lvalue) debe existir un puntero de tipo adecuado para recibir el valor devuelto. Preste atención a las declaraciones de punteros de los siguientes ejemplos: int* mptr1 = new int[3]; // L.4: Ok. int (* mptr1) = new int[3]; // L.5: Ok. int (* mptr2)[] = new int[3][10]; // L.6: Error int (* mptr2)[10] = new int[3][10]; // L.7: Ok. int (* mptr3)[][2] = new int[3][10][2]; // L.8: Error int (* mptr3)[10][2] = new int[3][10][2]; // L.9: Ok. int (* mptr4)[][2][5] = new int[3][10][2][5]; // L.10: Error int (* mptr4)[10][2][5] = new int[3][10][2][5]; // Ok. Comentario Las líneas 6, 8 y 10 compilan sin dificultad con Borland C++ 5.5, aunque producen error con Visual C++ 6.0 y Linux GCC v 2.95.3. En rigor los tipos de los punteros a la izquierda y derecha de la asignación no son iguales en estas líneas. Por ejemplo, en L.8 el tipo del Lvalue es int ( *)[ ][2], mientras que el Rvalue es int ( *)[10][2]. En estos casos es posible hacer un "casting" explícito para convertir el tipo de la derecha en el de la izquierda (es lo que hace Borland automáticamente). Observe que en L.4 el puntero a matriz de enteros de una dimensión int[3] se define como puntero-a-entero int*. Que en L.7, el puntero a matriz de enteros de dos dimensiones int[3][10] se define como puntero-a-matriz de enteros de una dimensión int ( *)[10]. Que en L.9 el puntero a matriz de tres dimensiones int[3][10][2] se define como puntero a matriz de enteros de dos dimensiones int ( *)[10][2]; y a así sucesivamente.

Ejemplo

El programa que sigue muestra el uso del operador new[] asignando espacio para una matriz bidimensional y de delete[ ] para desasignando después.

  1. include <exception>
  2. include <iostream.h>

void display(double **); // L3: función auxiliar-1 void borra(double **); // L4: función auxiliar-2 int fil = 3; // L5: Número de filas int col = 5; // L6: Número de columnas

int main(void) { // ========== double** data; // M1: try { // Controlar excepciones data = new double* [fil]; // M3: for (int j = 0; j < fil; j++) // data[j] = new double [col]; // Fase-2: Establecer columnas } catch (std::bad_alloc) { // capturar posibles errores cout << "Imposible asignar espacio. Saliendo..."; exit(-1); // terminar con error

}

for (int i = 0; i < fil; i++) // for (int j = 0; j < col; j++) data[i][j] = i + j; display(data); // mostrar datos borra(data); // borrar datos delete[] data; // A23: Borrar filas return 0; // terminar Ok. } void display(double **data) { // Función auxiliar-1 for (int i = 0; i < fil; i++) { for (int j = 0; j < col; j++) cout << data[i][j] << " "; cout << "\n";

}

} void borra(double **data) { // Función auxiliar-2

 for (int i = 0; i < fil; i++)   // A21:
   delete[] data[i];             // A22: Fase-1: Borrar columnas

} Salida: 0 1 2 3 4 1 2 3 4 5 2 3 4 5 6 Comentario Se trata de crear; mostrar, y borrar una matriz bidimensional M[3][5]. Los elementos serán de tipo double (podría ser otro tipo cualquiera, simple o abstracto). Las primeras sentencias simplemente declaran dos funciones auxiliares (encargadas de mostrar y borrar los elementos de la matriz), y establecen el número de filas y columnas. Como todo programa en que se manejen asignaciones de memoria con new, se dispone de un sistema de control para manejar cualquier posible fallo de este operador, que en tal caso lanzará una excepción bad_alloc. La matriz M será persistente (se creará en el montón) y estará referenciada mediante el correspondiente puntero. En este caso el puntero debe ser de tipo double** (puntero-a-puntero-a-double); lo denominamos mat y lo declaramos en M1 (mat es un objeto automático creado en la pila). La primera sentencia realmente interesante es M3: data = new double* [fil]; // M3: El puntero data se inicia con el resultado de crear una matriz de fil elementos tipo double* (puntero-a-double). Justamente porque cada elemento de esta matriz contendrá un puntero a una matriz de doubles (cada una de las cuales es una columna).

Véase también

Fuente

  • Cambiando la forma de operar de new y delete [1]. Consultado 20/11/2018
  • Diferencia entre Java y C++ [2]. Consultado 20/11/2018
  • Curso de programación en C++[3]. Consultado 20/11/2018