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
Ir a la versión completa