elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Recuerda que debes registrarte en el foro para poder participar (preguntar y responder)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  C++ - Problema con operador delete
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 3 Ir Abajo Respuesta Imprimir
Autor Tema: C++ - Problema con operador delete  (Leído 9,043 veces)
xaps

Desconectado Desconectado

Mensajes: 157



Ver Perfil
C++ - Problema con operador delete
« en: 13 Diciembre 2013, 18:50 pm »

Estoy desarrollando una clase Matriz, en la que le he incluido varias sobrecargas de operadores para poder trabajar con estas matrices de una manera más cómoda. El problema viene dado cuando entra en juego el operador de asignación, cuando usa la operación delete para liberar la memoria de la matriz y crear una copia del parámetro, que me da el siguiente error, además de un mapeado de memoria:
Código:
*** glibc detected *** ./test.exe: free(): invalid pointer: 0x0000000000401662 ***

Os adjunto el código de la clase y el código de test.exe:

Matriz.h
Código
  1. #include <iostream>
  2. #include <vector>
  3.  
  4. using namespace std;
  5.  
  6. class Matriz {
  7.  
  8. private:
  9.  
  10.  int nfilas;
  11.  int ncolumnas;
  12.  int **matr;
  13.  
  14. public:
  15.  
  16.  //Constructoras
  17.  Matriz();
  18.  Matriz(int filas, int columnas);
  19.  
  20.  //Destructora
  21.  ~Matriz();
  22.  
  23.  //Consultoras
  24.  int filas() const;
  25.  int columnas() const;
  26.  int consultar(int fila, int columna) const;
  27.  
  28.  //Modificadora
  29.  void modificar(int fila, int columna, int x);
  30.  
  31.  //Entrada / Salida
  32.  void leer();
  33.  void escribir();
  34.  
  35.  //Operadores
  36.  Matriz operator +(const Matriz &b) const;
  37.  Matriz operator -(const Matriz &b) const;
  38.  Matriz operator *(const Matriz &b) const;
  39.  Matriz operator =(const Matriz &b);
  40.  
  41.  bool operator ==(const Matriz &mat) const;
  42.  bool operator !=(const Matriz &mat) const;
  43. };
  44.  
  45. Matriz::Matriz() {}
  46.  
  47. Matriz::Matriz(int filas, int columnas)
  48. {
  49.  this->nfilas = filas;
  50.  this->ncolumnas = columnas;
  51.  
  52.  matr = new int* [filas];
  53.  for (int i = 0; i < filas; ++i)
  54.  {
  55.    matr[i] = new int [columnas];
  56.  }
  57. }
  58.  
  59. Matriz::~Matriz()
  60. {
  61.  delete matr;
  62. }
  63.  
  64. int Matriz::filas() const
  65. {
  66.  return nfilas;
  67. }
  68.  
  69. int Matriz::columnas() const
  70. {
  71.  return ncolumnas;
  72. }
  73.  
  74. int Matriz::consultar(int fila, int columna) const
  75. {
  76.  return matr[fila][columna];
  77. }
  78.  
  79. void Matriz::modificar(int fila, int columna, int x)
  80. {
  81.  matr[fila][columna] = x;
  82. }
  83.  
  84. void Matriz::leer()
  85. {
  86.  for (int i = 0; i < nfilas; ++i)
  87.    for (int j = 0; j < ncolumnas; ++j) cin >> matr[i][j];
  88. }
  89.  
  90. void Matriz::escribir()
  91. {
  92.  for (int i = 0; i < nfilas; ++i)
  93.  {
  94.    for (int j = 0; j < ncolumnas; ++j) cout << matr[i][j] << " ";
  95.    cout << endl;
  96.  }
  97. }
  98.  
  99. Matriz Matriz::operator +(const Matriz &b) const
  100. {
  101.  int filas = this->nfilas;
  102.  int columnas = this->ncolumnas;
  103.  
  104.  Matriz res(filas, columnas);
  105.  
  106.  for (int i = 0; i < filas; ++i)
  107.    for (int j = 0; j < columnas; ++j)
  108.      res.matr[i][j] = this->matr[i][j] + b.matr[i][j];
  109.  
  110.  return res;
  111. }
  112.  
  113. Matriz Matriz::operator -(const Matriz &b) const
  114. {
  115.  int filas = this->nfilas;
  116.  int columnas = this->ncolumnas;
  117.  
  118.  Matriz res(filas, columnas);
  119.  
  120.  for (int i = 0; i < filas; ++i)
  121.    for (int j = 0; j < columnas; ++j)
  122.      res.matr[i][j] = this->matr[i][j] - b.matr[i][j];
  123.  
  124.  return res;
  125. }
  126.  
  127. Matriz Matriz::operator *(const Matriz &b) const
  128. {
  129.  if (this->ncolumnas == b.nfilas)
  130.  {
  131.    int pos = this->ncolumnas;
  132.    int filas = this->nfilas;
  133.    int columnas = b.ncolumnas;
  134.  
  135.    Matriz res(filas, columnas);
  136.    for (int i = 0; i < filas; ++i)
  137.    {
  138.      for (int j = 0; j < columnas; ++j)
  139.      {
  140. int value = 0;
  141. for (int k = 0; k < pos; ++k) value += this->matr[i][k] * b.matr[k][j];
  142. res.matr[i][j] = value;
  143.      }
  144.    };
  145.    return res;
  146.  }
  147. }
  148.  
  149. Matriz Matriz::operator =(const Matriz &mat)
  150. {
  151.  if (this != &mat)
  152.  {
  153.    cout << "flag1" << endl;
  154.    delete this->matr;
  155.    cout << "flag2" << endl;
  156.    if (mat.matr)
  157.    {
  158.      this->nfilas = mat.nfilas;
  159.      this->ncolumnas = mat.ncolumnas;
  160.  
  161.      matr = new int* [nfilas];
  162.      for (int i = 0; i < nfilas; ++i)
  163.      {
  164. matr[i] = new int [ncolumnas];
  165.      }
  166.  
  167.      for (int i = 0; i < nfilas; ++i)
  168.      {
  169. for (int j = 0; j < ncolumnas; ++j)
  170. {
  171.  matr[i][j] = mat.matr[i][j];
  172. }
  173.      }
  174.    }
  175.    else this->matr = NULL;
  176.  }
  177.  return *this;
  178. }
  179.  
  180. bool Matriz::operator ==(const Matriz &mat) const
  181. {
  182.  for (int i = 0; i < nfilas; ++i)
  183.    for (int j = 0; j < ncolumnas; ++j)
  184.      if (this->matr[i][j] != mat.matr[i][j]) return false;
  185.  
  186.  return true;
  187. }
  188.  
  189. bool Matriz::operator !=(const Matriz &mat) const
  190. {
  191.  for (int i = 0; i < nfilas; ++i)
  192.    for (int j = 0; j < ncolumnas; ++j)
  193.      if (this->matr[i][j] != mat.matr[i][j]) return true;
  194.  
  195.  return false;
  196. }
  197.  

Código
  1. #include "Matriz.h"
  2.  
  3. int main()
  4. {
  5.  int f1, c1, f2, c2;
  6.  
  7.  cout << "Introduce el tamaño de la primera matriz:" << endl;
  8.  cin >> f1 >> c1;
  9.  Matriz mat1(f1, c1);
  10.  cout << "Introduce los valores de la matriz:" << endl;
  11.  mat1.leer();
  12.  
  13.  cout << "Introduce el tamaño de la segunda matriz:" << endl;
  14.  cin >> f2 >> c2;
  15.  Matriz mat2(f2, c2);
  16.  cout << "Introduce los valores de la matriz:" << endl;
  17.  mat2.leer();
  18.  
  19.  
  20.  if (c1 == f2)
  21.  {
  22.    Matriz res;
  23.    res = mat1 * mat2;
  24.  
  25.    res.escribir();
  26.  }
  27. }
  28.  

He probado varias cosas, como cambiar delete por delete[], o intentar eliminar los vectores individualmente, pero ninguna ha dado resultado. Algo debo estar haciendo mal, pero no encuentro el error. Si le pudierais echar un ojo me haríais un favor.

Muchas gracias.


« Última modificación: 14 Diciembre 2013, 12:52 pm por xaps » En línea

"The programmers of tomorrow are the wizards of the future" - Gave Newel
amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: C++ - Problema con operador delete
« Respuesta #1 en: 13 Diciembre 2013, 22:39 pm »

Código
  1. Matriz::~Matriz()
  2. {
  3. delete matr;
  4. }
Eso está mal hecho, tienes que borrar al contrario que como la creas (primero con un for borras todos los vectores y despues borras el puntero principal).

Código
  1. Matriz::~Matriz()
  2. {
  3. for (int i = 0; i < nfilas;i++) delete[] matr[i];
  4. delete[] matr;
  5. }


En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
xaps

Desconectado Desconectado

Mensajes: 157



Ver Perfil
Re: C++ - Problema con operador delete
« Respuesta #2 en: 14 Diciembre 2013, 12:43 pm »

Código
  1. Matriz::~Matriz()
  2. {
  3. delete matr;
  4. }
Eso está mal hecho, tienes que borrar al contrario que como la creas (primero con un for borras todos los vectores y despues borras el puntero principal).

Código
  1. Matriz::~Matriz()
  2. {
  3. for (int i = 0; i < nfilas;i++) delete[] matr[i];
  4. delete[] matr;
  5. }

Gracias por la explicación. Eso es a lo que me refería cuando decía de eliminar los vectores individualmente. No me daba resultado por un error en el código de la sobrecarga del operador de asignación, en el que me pongo a eliminar los datos de matr sin verificar que esté vacío. Pero ahora, una vez arreglado ésto, me ocurre una cosa bastante curiosa que me produce un error de segmentación. Primero adjunto las funciones que he arreglado, y luego comento cual es el error que estoy teniendo ahora:

~Matriz();
Código
  1. Matriz::~Matriz()
  2. {
  3.  for (int i = 0; i < this->nfilas; ++i)
  4.  {
  5.    cout << "~fila " << i << endl;
  6.    delete[] this->matr[i];
  7.  }
  8.  delete[] this->matr;
  9. }

Matriz operator =(const Matriz &mat);
Código
  1. Matriz Matriz::operator =(const Matriz &mat)
  2. {
  3.  cout << "asignacion" << endl;
  4.  if (this != &mat)
  5.  {
  6.    if (this != NULL)
  7.    {
  8.      cout << "flag1" << endl;
  9.  
  10.      for (int i = 0; i < this->nfilas; ++i)
  11.      {
  12. cout << "fila " << i << endl;
  13. delete[] this->matr[i];
  14.      }
  15.      delete[] this->matr;
  16.    }
  17.  
  18.    cout << "flag2" << endl;
  19.    if (mat.matr)
  20.    {
  21.      this->nfilas = mat.nfilas;
  22.      this->ncolumnas = mat.ncolumnas;
  23.  
  24.      matr = new int* [nfilas];
  25.      for (int i = 0; i < nfilas; ++i)
  26.      {
  27. matr[i] = new int [ncolumnas];
  28.      }
  29.  
  30.      for (int i = 0; i < nfilas; ++i)
  31.      {
  32. for (int j = 0; j < ncolumnas; ++j)
  33. {
  34.  matr[i][j] = mat.matr[i][j];
  35. }
  36.      }
  37.    }
  38.    else this->matr = NULL;
  39.  }
  40.  return *this;
  41. }

Pues bien, el error es el siguiente: Parece que justo antes de realizar la asignación el destructor por defecto se carga la matriz, y cuando en el delete de la sobrecarga de asignación intenta acceder a la posición "i" le da un error de segmentación. He llegado a esta conclusión mediante la salida que me ha dado el programa. Os enseño cual es la entrada que le he dado y cual es la salida que me ha devuelto:

Entrada:
Código:
2 2
1 1 0 1
2 2
1 0 1 1

Salida:
Código:
~fila 0
~fila 1
asignacion
flag1
fila 0
Violación de segmento

Como podéis comprobar, primero entra al destructor por defecto y a continuación intenta realizar la asignación. El problema es que no se ni que matriz elimina, ni porqué la matriz a la que se le realiza la asignación entra dentro de la condición (teóricamente, la matriz res tiene matr = NULL, ¿no?).

Muchas gracias de nuevo.
« Última modificación: 14 Diciembre 2013, 12:50 pm por xaps » En línea

"The programmers of tomorrow are the wizards of the future" - Gave Newel
amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: C++ - Problema con operador delete
« Respuesta #3 en: 14 Diciembre 2013, 13:18 pm »

Código
  1. if (this != NULL)

Esa condición siempre va a ser cierta xD. Creo que te referias a this.matr, supongo que de ahí viene el error de segmentación (borrar cuando ni siquiera tienes matriz).

Por cierto no me parece adecuado que copypastees el destructor ahí, yo me haría una función privada "borrar". Y esa función la llamo desde el destructor y desde allí, por reciclar código más que nada.
En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
xaps

Desconectado Desconectado

Mensajes: 157



Ver Perfil
Re: C++ - Problema con operador delete
« Respuesta #4 en: 14 Diciembre 2013, 14:32 pm »

Código
  1. if (this != NULL)

Esa condición siempre va a ser cierta xD. Creo que te referias a this.matr, supongo que de ahí viene el error de segmentación (borrar cuando ni siquiera tienes matriz).

Por cierto no me parece adecuado que copypastees el destructor ahí, yo me haría una función privada "borrar". Y esa función la llamo desde el destructor y desde allí, por reciclar código más que nada.

Vaya error mas tonto... jajaj Gracias!

Sobre lo de la función, ni se me había ocurrido. Ya lo he implementado.
Otro "error" que tenia era que en la constructora por defecto no iniciaba matr a NULL, y provocaba que una vez arreglado ese error tan tonto me diera violación de segmento de nuevo ya que aún pasaba la condición.

Pero ahora me vuelve a dar un error de nuevo con la destructora (siento ser tan pesado, pero aún no hemos dado ni memoria dinámica en la universidad y lo estoy haciendo por simple entretenimiento y curiosidad, por lo que estoy investigando por cuenta propia y hay cosas que se me escapan). Primero de todo, volveré a adjuntar la clase tal como la tengo ahora, y a continuación pegaré la salida que me da el programa.

Clase Matriz:
Código
  1. #include <iostream>
  2. #include <vector>
  3.  
  4. using namespace std;
  5.  
  6. class Matriz {
  7.  
  8. private:
  9.  
  10.  int nfilas;
  11.  int ncolumnas;
  12.  int **matr;
  13.  
  14.  void borrar();
  15.  
  16. public:
  17.  
  18.  //Constructoras
  19.  Matriz();
  20.  Matriz(int filas, int columnas);
  21.  
  22.  //Destructora
  23.  ~Matriz();
  24.  
  25.  //Consultoras
  26.  int filas() const;
  27.  int columnas() const;
  28.  int consultar(int fila, int columna) const;
  29.  
  30.  //Modificadora
  31.  void modificar(int fila, int columna, int x);
  32.  
  33.  //Entrada / Sortida
  34.  void leer();
  35.  void escribir();
  36.  
  37.  //Operadores
  38.  Matriz operator +(const Matriz &b) const;
  39.  Matriz operator -(const Matriz &b) const;
  40.  Matriz operator *(const Matriz &b) const;
  41.  Matriz operator =(const Matriz &b);
  42.  
  43.  bool operator ==(const Matriz &mat) const;
  44.  bool operator !=(const Matriz &mat) const;
  45. };
  46.  
  47. Matriz::Matriz() {matr = NULL;}
  48.  
  49. Matriz::Matriz(int filas, int columnas)
  50. {
  51.  this->nfilas = filas;
  52.  this->ncolumnas = columnas;
  53.  
  54.  matr = new int* [filas];
  55.  for (int i = 0; i < filas; ++i)
  56.  {
  57.    matr[i] = new int [columnas];
  58.  }
  59. }
  60.  
  61. Matriz::~Matriz()
  62. {
  63.  cout << "destructora" << endl;
  64.  borrar();
  65. }
  66.  
  67. void Matriz::borrar()
  68. {
  69.  if (this->matr != NULL)
  70.  {
  71.    for (int i = 0; i < nfilas; ++i)
  72.    {
  73.      cout << "fila " << i << endl;
  74.      delete[] matr[i];
  75.    }
  76.    delete[] matr;
  77.    matr = NULL;
  78.  }
  79. }
  80.  
  81. int Matriz::filas() const { return nfilas;}
  82.  
  83. int Matriz::columnas() const { return ncolumnas;}
  84.  
  85. int Matriz::consultar(int fila, int columna) const { return matr[fila][columna];}
  86.  
  87. void Matriz::modificar(int fila, int columna, int x) { matr[fila][columna] = x;}
  88.  
  89. void Matriz::leer()
  90. {
  91.  for (int i = 0; i < nfilas; ++i)
  92.    for (int j = 0; j < ncolumnas; ++j) cin >> matr[i][j];
  93. }
  94.  
  95. void Matriz::escribir()
  96. {
  97.  cout << "flag3" << endl;
  98.  for (int i = 0; i < nfilas; ++i)
  99.  {
  100.    for (int j = 0; j < ncolumnas; ++j) cout << matr[i][j] << " ";
  101.    cout << endl;
  102.  }
  103. }
  104.  
  105. Matriz Matriz::operator +(const Matriz &b) const
  106. {
  107.  int filas = this->nfilas;
  108.  int columnas = this->ncolumnas;
  109.  
  110.  Matriz res(filas, columnas);
  111.  
  112.  for (int i = 0; i < filas; ++i)
  113.    for (int j = 0; j < columnas; ++j)
  114.      res.matr[i][j] = this->matr[i][j] + b.matr[i][j];
  115.  
  116.  return res;
  117. }
  118.  
  119. Matriz Matriz::operator -(const Matriz &b) const
  120. {
  121.  int filas = this->nfilas;
  122.  int columnas = this->ncolumnas;
  123.  
  124.  Matriz res(filas, columnas);
  125.  
  126.  for (int i = 0; i < filas; ++i)
  127.    for (int j = 0; j < columnas; ++j)
  128.      res.matr[i][j] = this->matr[i][j] - b.matr[i][j];
  129.  
  130.  return res;
  131. }
  132.  
  133. Matriz Matriz::operator *(const Matriz &b) const
  134. {
  135.  if (this->ncolumnas == b.nfilas)
  136.  {
  137.    int pos = this->ncolumnas;
  138.    int filas = this->nfilas;
  139.    int columnas = b.ncolumnas;
  140.  
  141.    Matriz res(filas, columnas);
  142.    for (int i = 0; i < filas; ++i)
  143.    {
  144.      for (int j = 0; j < columnas; ++j)
  145.      {
  146. int value = 0;
  147. for (int k = 0; k < pos; ++k) value += this->matr[i][k] * b.matr[k][j];
  148. res.matr[i][j] = value;
  149.      }
  150.    };
  151.    return res;
  152.  }
  153. }
  154.  
  155. Matriz Matriz::operator =(const Matriz &mat)
  156. {
  157.  cout << "asignacion" << endl;
  158.  if (this != &mat)
  159.  {
  160.    cout << "flag1" << endl;
  161.    borrar();
  162.    cout << "flag2" << endl;
  163.  
  164.    if (mat.matr)
  165.    {
  166.      this->nfilas = mat.nfilas;
  167.      this->ncolumnas = mat.ncolumnas;
  168.  
  169.      matr = new int* [nfilas];
  170.      for (int i = 0; i < nfilas; ++i)
  171. matr[i] = new int [ncolumnas];
  172.  
  173.      for (int i = 0; i < nfilas; ++i)
  174.      {
  175. for (int j = 0; j < ncolumnas; ++j)
  176.  matr[i][j] = mat.matr[i][j];
  177.      }
  178.    }
  179.    else this->matr = NULL;
  180.  }
  181.  return *this;
  182. }
  183.  
  184. bool Matriz::operator ==(const Matriz &mat) const
  185. {
  186.  for (int i = 0; i < nfilas; ++i)
  187.    for (int j = 0; j < ncolumnas; ++j)
  188.      if (this->matr[i][j] != mat.matr[i][j]) return false;
  189.  
  190.  return true;
  191. }
  192.  
  193. bool Matriz::operator !=(const Matriz &mat) const
  194. {
  195.  for (int i = 0; i < nfilas; ++i)
  196.    for (int j = 0; j < ncolumnas; ++j)
  197.      if (this->matr[i][j] != mat.matr[i][j]) return true;
  198.  
  199.  return false;
  200. }
  201.  

Los datos de entrada son los mismos de antes, y la salida es la siguiente:
Código:
destructora
fila 0
fila 1
asignacion
flag2
destructora
fila 0
fila 1
destructora
fila 0
*** glibc detected *** ./test.exe: double free or corruption (out): 0x0000000001a590e0 ***
Además del mapeado de memoria que se da con este tipo de error.

Se puede ver como la asignación aparentemente la realiza bien, pero luego, antes de ejecutar la función leer() elimina dos matrices, que sospecho que serán mat1 y mat2 (ya que no se vuelven a usar en el programa) y es cuando salta el mensaje de error. Lo extraño es que ninguna de las dos matrices puede haber sido modificada previamente, ya que el operador de multiplicación y su parámetro son constantes y la asignación trabaja con la matriz resultado de la multiplicación (la que se obtiene del return). Por lo que me lleva a sospechar que la primera matriz que elimina la destructora (la que se elimina antes de hacer la asignación) es la que luego se vuelve a intentar eliminar y provoca el error. Entonces, he pensado en incluir en la función borrar() la misma condición que en la sobrecarga de asignación (y eliminarla de ésta), pero el error sigue ahí (todo esto ya está reflejado en el código de la clase incluido arriba). También he añadido la asignación matr = NULL, aunque no sé si al usar la operación delete un puntero queda con el valor NULL asignado o no.

También he encontrado esto buscando información sobre el delete:
Citar
Cuando se usa el operador delete con un puntero nulo, no se realiza ninguna acción. Esto permite usar el operador delete con punteros sin necesidad de preguntar si es nulo antes.
Fuente: http://c.conclase.net/curso/?cap=013b

Por lo tanto, no debería ser necesaria la condición if (matr != NULL);, ¿no?

¿Alguna idea de que es lo que puede estar ocurriendo?

Muchas gracias!
En línea

"The programmers of tomorrow are the wizards of the future" - Gave Newel
amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: C++ - Problema con operador delete
« Respuesta #5 en: 14 Diciembre 2013, 15:19 pm »

¿Que código has usado para las pruebas?

PD: No sabía lo de los punteros null y delete. Siempre se aprende algo nuevo  :silbar:
En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
xaps

Desconectado Desconectado

Mensajes: 157



Ver Perfil
Re: C++ - Problema con operador delete
« Respuesta #6 en: 14 Diciembre 2013, 16:20 pm »

¿Que código has usado para las pruebas?

PD: No sabía lo de los punteros null y delete. Siempre se aprende algo nuevo  :silbar:

El mismo que el del post principal, lo único que he cambiado ha sido la clase.
Te lo adjunto de todas formas:
Código
  1. #include "Matriz.h"
  2.  
  3. int main()
  4. {
  5.  int f1, c1, f2, c2;
  6.  
  7.  cout << "Introduce el tamaño de la primera matriz:" << endl;
  8.  cin >> f1 >> c1;
  9.  Matriz mat1(f1, c1);
  10.  cout << "Introduce los valores de la matriz:" << endl;
  11.  mat1.leer();
  12.  
  13.  cout << "Introduce el tamaño de la segunda matriz:" << endl;
  14.  cin >> f2 >> c2;
  15.  Matriz mat2(f2, c2);
  16.  cout << "Introduce los valores de la matriz:" << endl;
  17.  mat2.leer();
  18.  
  19.  
  20.  if (c1 == f2)
  21.  {
  22.    Matriz res;
  23.    res = mat1 * mat2;
  24.  
  25.    res.escribir();
  26.  }
  27. }
  28.  
En línea

"The programmers of tomorrow are the wizards of the future" - Gave Newel
amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: C++ - Problema con operador delete
« Respuesta #7 en: 14 Diciembre 2013, 16:58 pm »

Vale ya he arreglado el operador de asignación, el problema es que no devuelves una referencia sino un nuevo objeto matriz. Como no tienes hecho un constructor copia se copian los punteros literales, eso te provoca problemas...

Simplemente haz estos dos cambios:

- Haz que el operador = devuelva Matriz& en vez de un nuevo objeto.
- Create un constructor copia tal que así:

Código
  1. Matriz::Matriz(const Matriz &m)
  2. {
  3.    *this = m;
  4. }

Con eso a mí me funciona perfecto.
En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
xaps

Desconectado Desconectado

Mensajes: 157



Ver Perfil
Re: C++ - Problema con operador delete
« Respuesta #8 en: 14 Diciembre 2013, 17:08 pm »

Vale ya he arreglado el operador de asignación, el problema es que no devuelves una referencia sino un nuevo objeto matriz. Como no tienes hecho un constructor copia se copian los punteros literales, eso te provoca problemas...

Simplemente haz estos dos cambios:

- Haz que el operador = devuelva Matriz& en vez de un nuevo objeto.
- Create un constructor copia tal que así:

Código
  1. Matriz::Matriz(const Matriz &m)
  2. {
  3.    *this = m;
  4. }

Con eso a mí me funciona perfecto.

¿A que te refieres con "Como no tienes hecho un constructor copia se copian los punteros literales"? No entiendo cual es el problema aún :S
En línea

"The programmers of tomorrow are the wizards of the future" - Gave Newel
amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: C++ - Problema con operador delete
« Respuesta #9 en: 14 Diciembre 2013, 17:33 pm »

¿A que te refieres con "Como no tienes hecho un constructor copia se copian los punteros literales"? No entiendo cual es el problema aún :S
A ver, tu tenías definido el operador = para que devolviese un nuevo objeto matriz.

Como has hecho return *this esa matriz era una copia de this. Para hacer copias de un objeto se llama al constructor copia.

Si no has definido el constructor copia, el compilador crea uno por ti. El problema esque el compilador hace la copia literal. Lo que implica que se copian los punteros de la matriz tal cual.

Cuando esa matriz "copia" desaparece, se llama al destructor y se libera la memoria. Cuando la matriz "original" desaparece, se vuelve a llamar al destructor y se libera la misma memoria (¡Los punteros son iguales!). De ahí la excepción en tiempo de ejcución.

Aunque el error se solucionaría poniendo Matriz& en el retorno del operador =, no puedes dejarlo así porque ya sabes que las copias te van a fallar. Asi que te he rehecho el constructor copia (y para no copy&pastear el código, me he aprovechado del operador de asignación que hemos definido).

PD: Ya que estoy, los demás operadores (+ - *) también debería devolver Matriz& en vez de Matriz. De lo contrario estarás haciendo copias al montón :silbar:
En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
Páginas: [1] 2 3 Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines