Programación General > C/C++

 Clase matriz "violación de segmento"

(1/1)

antlcn:
Hola, estoy haciendo una clase matriz con sus constructores, operadores, etc y me da un fallo de segmentación tras la comprobación "Ok4" del main, les adjunto el codigo:


main.cpp:

--- Código: C++ ---#include <matrix.h>#include <iostream>using namespace std;using namespace storage; //template Function that prints a matrix template<class Type>void print(Matriz<Type> &M){for(unsigned int i=0;i<M.getNRows();i++){for(unsigned int j=0;j<M.getNCols();j++)cout<<M.get(i,j)<< " ";cout<<endl;}} int main(int argc,char **argv){Matriz<float> M;M.resize(10,10);cout<<"ok1"<<endl;M.setIdentity();cout<<"ok2"<<endl;print(M);cout<<"ok3"<<endl;Matriz<float> M2(M);print(M2);cout<<"ok4"<<endl;Matriz<float> M3(10,10);M3=M+M2;cout<<"ok5"<<endl;print(M3);cout<<"ok6"<<endl;//check the resultfor(unsigned int i=0;i<M3.getNRows();i++){for(unsigned int j=0;j<M.getNCols();j++)if (i!=j)assert(M3.get(i,j)==0);else assert(M3.get(i,j)==2);}cout<<"Perfect"<<endl;}  


matrix.h:

--- Código: C++ ---#ifndef _Matrix_H_#define _Matrix_H_#include <cassert>#include <cstdlib> using namespace std;namespace storage{    template<class Type>        class Matriz        {            public:                /* constructor vacio                 */                inline Matriz();                /* constructor copia                 */                inline Matriz(const Matriz &M);                /* constructor parametrizado                 */                inline Matriz(unsigned int nRows, unsigned int nCols);                /* redimensionar la matriz                 */                inline void resize(unsigned int nRows, unsigned int nCols);                /* indica el numero de filas                */                unsigned int getNRows() { return _nRows;}                /* indica el numero de columnas                 */                unsigned int getNCols() { return _nCols;}                /* retorna el valor indicado por las variables                 */                inline Type & get(unsigned int r,unsigned int c);                /* hace que la matriz sea la indentidad                 */                inline void setIdentity();                /* operador de asignacion                 */                inline Matriz & operator=(const Matriz &M);                /* realiza la suma de dos matrices                 */                inline Matriz & operator+(const Matriz &M);                /* destructor                 */                inline ~Matriz();                        private:             Type **_data;            unsigned int _nRows;            unsigned int _nCols;        };          //////////////////////////////////////////////////////template<class Type>Matriz<Type>::Matriz(){  _data=NULL;  _nRows=0;  _nCols=0;} //////////////////////////////////////////////////////template<class Type>Matriz<Type>::Matriz(const Matriz &M){  int i,j;  _nRows=M._nRows;  _nCols=M._nCols;  _data= new Type*[_nRows];  for(i=0;i<_nRows;i++){     _data[i]=new Type[_nCols];  }  for(i=0;i<_nRows;i++){    for(j=0;j<_nCols;j++){      _data[i][j]=M._data[i][j];    }  }} //////////////////////////////////////////////////////template<class Type>Matriz<Type>::Matriz(unsigned int nRows, unsigned int nCols){  int i;  _nRows=nRows;  _nCols=nCols;  if(_data==NULL){  _data= new Type*[_nRows];  for(i=0;i<_nRows;i++){     _data[i]=new Type[_nCols];  }  }} //////////////////////////////////////////////////////template<class Type>void Matriz<Type>::resize(unsigned int nRows, unsigned int nCols){  int i;  if(_data!=NULL){    for(i=0;i<nRows;i++){      delete []_data[i];    }    delete []_data;  }  Matriz(nRows, nCols);} //////////////////////////////////////////////////////template<class Type>Type & Matriz<Type>::get(unsigned int r, unsigned int c){  return _data[r][c];}  //////////////////////////////////////////////////////template<class Type>void Matriz<Type>::setIdentity(){  int i,j;  for(i=0;i<_nRows;i++){    for(j=0;j<_nCols;j++){      if(i==j)    _data[i][j]=1;      else    _data[i][j]=0;    }  }} //////////////////////////////////////////////////////template<class Type>Matriz<Type> & Matriz<Type>::operator=(const Matriz &M){  int i,j;  if(_data==NULL)    Matriz(M._nRows, M._nCols);  for(i=0;i<_nRows;i++){    for(j=0;j<_nCols;j++){      _data[i][j]=M._data[i][j];    }  }  return *this;} //////////////////////////////////////////////////////template<class Type>Matriz<Type> & Matriz<Type>::operator+(const Matriz &M){  int i,j;  if(_data==NULL)    Matriz(M._nRows, M._nCols);  for(i=0;i<_nRows;i++){    for(j=0;j<_nCols;j++){      _data[i][j]=_data[i][j]+M._data[i][j];    }  }  return *this;} //////////////////////////////////////////////////////template<class Type>Matriz<Type>::~Matriz(){  int i;  if(_data!=NULL){    for(i=0;i<_nRows;i++){      delete []_data[i];    }    delete []_data;  }}}; #endif  

gracias de antemano.

Amilius:
El problema está en el uso del constructor en tu operador '=', '+' y el método resize.

Tienes que modificar tu código para mover el código del constructor a resize. De tal forma que sólo tengas new y delete en la función resize. El destructor podría llamar a resize (0,0) para liberar la memoria. Si resize recibe un parámetro que sea 0 debería liberar la memoria y poner _data en 0.

antlcn:
que tendría que hacer en los operadores "+" "=" ? que no veo el fallo.

Amilius:
El problema es que no estás reservando memoria y sigues con tu puntero en 0. Esa forma de llamar a un constructor hace que OTRO objeto sea creado en pila y destruido antes de ejecutar la siguiente línea.

Navegación

[0] Índice de Mensajes

Ir a la versión completa