я пишу класс для матрицы с такими функциями:
когда я запускаю программу, она выводит неправильные значения и ошибку double free or corruption (out)
. помогите найти в чем проблема. при вводе матрицы 2х2, она выводит только одно правильное значение для (+, -). а при вводе матрицы 3х3, то 4 правильных значения из 9.
#include <iostream>
using namespace std;
class matrix
{
int Row, Col; //строки и столбцы
double **Value; // элементы матрицы
public:
matrix(int, int); //конструктор
matrix(matrix&); //копирующий конструктор - создает копию объекта m
int GetRow(); //метод получает значение числа строк
int GetCol(); //метод получает значение числа столбцов
double& operator()(int, int); //перегрузка скобок для матрицы
friend istream& operator>>(istream &istr, matrix &m);//перегрузка оператора ввода
friend ostream& operator<<(ostream &ostr, matrix &m);//перегрузка оператора вывода
friend matrix operator+(matrix &m1, matrix &m2);//перегрузка оператора плюс (бинарный)
friend matrix operator-(matrix &m1, matrix &m2);//перегрузка оператора минус (бинарный)
~matrix(); //деструктор
};
matrix::matrix(int row,int col)
{
Row=row; //переменным Row и Col присваиются вводимые значения числа строк и столбцов матрицы
Col=col;
Value=new double*[row]; //конструктор создает двумерный динамический массив
for (int i=0; i<row; i++) Value[i]=new double[col];
}
matrix::matrix(matrix& m) //копирующий конструктор - создает копию матрицы m
{
Value=new double *[Row];
for (int i=0; i<Row; i++) Value[i]=new double[Col];
for (int i=0; i<Row; i++)
{
for (int j=0; j<Col; j++)
Value[i][j] = m(i,j);
} // значения элементов матрицы будут такими же, как у матрицы m
}
int matrix::GetRow() //функция получает значение числа строк
{
return (Row);
}
int matrix::GetCol() //функция получает значение числа столбцов
{
return (Col);
}
istream &operator>>(istream &istr, matrix &m) // перегрузка оператора ввода матрицы
{
for (int i=0; i<m.GetRow(); i++)
for (int j=0; j<m.GetCol(); j++)
istr>>m(i, j);
return(istr);
}
ostream &operator<<(ostream &ostr, matrix &m) //перегрузка оператора вывода матрицы
{
for (int i=0; i<m.GetRow(); i++)
{
for (int j=0; j<m.GetCol(); j++)
ostr<<m(i,j)<<"\t";
ostr<<"\n";
}
return(ostr);
}
matrix operator+(matrix &m1, matrix &m2) //перегрузка оператора плюс (бинарный)
{
matrix temp(m1.GetRow(),m1.GetCol());
for (int i = 0; i<m1.GetRow(); i++)
for (int j = 0; j<m1.GetCol(); j++)
temp(i,j)=m1(i,j)+m2(i,j);
return(temp);
}
matrix operator-(matrix &m1, matrix &m2) //перегрузка оператора минус (бинарный)
{
matrix temp1(m1.GetRow(),m1.GetCol());
for (int i = 0; i<m1.GetRow(); i++)
for (int j = 0; j<m1.GetCol(); j++)
temp1(i,j)=m1(i,j)-m2(i,j);
return(temp1);
}
double& matrix::operator()(int row, int col)//перегрузка круглых скобок для матрицы.
{ // Если m - матрица, то m(i,j) будет
return (Value[row][col]); //означать i,j-тый элемент матрицы
}
matrix::~matrix() //деструктор
{
for (int i=0; i<Row; i++)
delete[] Value[i]; //деструктор удаляет из памяти динамический массив, созданный конструктором
delete[] Value;
}
int main()
{
int m,n;
cout<<"enter number of rows and columns of matrices: "; cin>>m>>n;
matrix a(m,n);
matrix b(m,n);
matrix c(m,n);
cout<<"enter matrix A:\n"; cin>>a;
cout<<"enter matrix B:\n"; cin>>b;
c=a+b;
cout<<"sum of two matrices A and B :\n"<<c;
c=a-b;
cout<<"subtraction of two matrices A and B :\n"<<c;
return 0;
}
вот как работает программа
$ ./a.out
enter number of rows and columns of matrices: 2 2
enter matrix A:
4 5
6 3
enter matrix B:
8 9
7 1
sum of two matrices A and B :
0 1.63042e-322
8.66416e-317 4
subtraction of two matrices A and B :
0 1.63042e-322
8.66417e-317 2
*** Error in `./a.out': double free or corruption (out): 0x00000000010b95c0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fc213dec7e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7fc213df537a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fc213df953c]
./a.out[0x40107b]
./a.out[0x401220]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7fc213d95830]
./a.out[0x4009c9]
======= Memory map: ========
00400000-00402000 r-xp 00000000 00:2e 1178660 /home/neo/Desktop/class matrix/a.out
00601000-00602000 r--p 00001000 00:2e 1178660 /home/neo/Desktop/class matrix/a.out
00602000-00603000 rw-p 00002000 00:2e 1178660 /home/neo/Desktop/class matrix/a.out
010a7000-010d9000 rw-p 00000000 00:00 0 [heap]
7fc20c000000-7fc20c021000 rw-p 00000000 00:00 0
7fc20c021000-7fc210000000 ---p 00000000 00:00 0
7fc213a6c000-7fc213b74000 r-xp 00000000 08:04 267638 /lib/x86_64-linux-gnu/libm-2.23.so
7fc213b74000-7fc213d73000 ---p 00108000 08:04 267638 /lib/x86_64-linux-gnu/libm-2.23.so
7fc213d73000-7fc213d74000 r--p 00107000 08:04 267638 /lib/x86_64-linux-gnu/libm-2.23.so
7fc213d74000-7fc213d75000 rw-p 00108000 08:04 267638 /lib/x86_64-linux-gnu/libm-2.23.so
7fc213d75000-7fc213f35000 r-xp 00000000 08:04 267650 /lib/x86_64-linux-gnu/libc-2.23.so
7fc213f35000-7fc214135000 ---p 001c0000 08:04 267650 /lib/x86_64-linux-gnu/libc-2.23.so
7fc214135000-7fc214139000 r--p 001c0000 08:04 267650 /lib/x86_64-linux-gnu/libc-2.23.so
7fc214139000-7fc21413b000 rw-p 001c4000 08:04 267650 /lib/x86_64-linux-gnu/libc-2.23.so
7fc21413b000-7fc21413f000 rw-p 00000000 00:00 0
7fc21413f000-7fc214155000 r-xp 00000000 08:04 267576 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fc214155000-7fc214354000 ---p 00016000 08:04 267576 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fc214354000-7fc214355000 rw-p 00015000 08:04 267576 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fc214355000-7fc2144c7000 r-xp 00000000 08:04 1509 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fc2144c7000-7fc2146c7000 ---p 00172000 08:04 1509 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fc2146c7000-7fc2146d1000 r--p 00172000 08:04 1509 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fc2146d1000-7fc2146d3000 rw-p 0017c000 08:04 1509 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fc2146d3000-7fc2146d7000 rw-p 00000000 00:00 0
7fc2146d7000-7fc2146fd000 r-xp 00000000 08:04 267512 /lib/x86_64-linux-gnu/ld-2.23.so
7fc2148c8000-7fc2148cd000 rw-p 00000000 00:00 0
7fc2148f9000-7fc2148fc000 rw-p 00000000 00:00 0
7fc2148fc000-7fc2148fd000 r--p 00025000 08:04 267512 /lib/x86_64-linux-gnu/ld-2.23.so
7fc2148fd000-7fc2148fe000 rw-p 00026000 08:04 267512 /lib/x86_64-linux-gnu/ld-2.23.so
7fc2148fe000-7fc2148ff000 rw-p 00000000 00:00 0
7ffdf38fc000-7ffdf391d000 rw-p 00000000 00:00 0 [stack]
7ffdf39b3000-7ffdf39b5000 r--p 00000000 00:00 0 [vvar]
7ffdf39b5000-7ffdf39b7000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
Update после этого ответа
после исправления все сработало(+, - и *). я также хотел найти обратную матрицу(для А и В).
matrix matrix::inverse(matrix &m) //метод нахождения обратной матрицы
{
double t;
int n=m.GetRow();
for(int i=0;i<n;i++)
{
for(int j=n;j<2*n;j++)
{
if(i==j-n)
m(i,j)=1;
else
m(i,j)=0;
}
}
for(int i=0;i<n;i++)
{
t=m(i,i);
for(int j=i;j<2*n;j++)
m(i,j)/=t;
for(int j=0;j<n;j++)
{
if(i!=j)
{
t=m(j,i);
for(int k=0;k<2*n;k++)
m(j,k)-=t*m(i,k);
}
}
}
return (m);
}
...
c=a.inverse(a);
но там выводится вот это:
...
inverse of matrix A:
1 0
0 1
Segmentation fault
Для начала: чему у вас в первых же строках равны Row
и Col
:
matrix::matrix(matrix& m) //копирующий конструктор - создает копию матрицы m
{
Value=new double *[Row];
for (int i=0; i<Row; i++) Value[i]=new double[Col];
? (кстати, копирующему конструктору лучше передавать константную ссылку).
А оператора присваивания нет вообще - а сгенерированный по умолчанию будет выполнять поверхностное копирование - указателей, а не того, на что они указывают - со всеми вытекающими типа двойного удаления etc...
Update
Простите, нет времени на долгие объяснения - разберитесь сами, как работает исправленный код:
#include <iostream>
using namespace std;
class matrix
{
int Row, Col; //строки и столбцы
double **Value; // элементы матрицы
public:
matrix(int, int); //конструктор
matrix(const matrix&); //копирующий конструктор - создает копию объекта m
int GetRow(); //метод получает значение числа строк
int GetCol(); //метод получает значение числа столбцов
double& operator()(int, int); //перегрузка скобок для матрицы
double operator()(int, int) const; //перегрузка скобок для матрицы
friend istream& operator>>(istream &istr, matrix &m);//перегрузка оператора ввода
friend ostream& operator<<(ostream &ostr, matrix &m);//перегрузка оператора вывода
friend matrix operator+(matrix &m1, matrix &m2);//перегрузка оператора плюс (бинарный)
friend matrix operator-(matrix &m1, matrix &m2);//перегрузка оператора минус (бинарный)
~matrix(); //деструктор
matrix& operator=(const matrix& m)
{
matrix tmp(m);
swap(tmp);
return *this;
}
private:
void swap(matrix&m)
{
{
int tmp = Row; Row = m.Row; m.Row = tmp;
tmp = Col; Col = m.Col; m.Col = tmp;
}
double ** tmp = Value; Value = m.Value; m.Value = tmp;
}
};
matrix::matrix(int row,int col)
{
Row=row; //переменным Row и Col присваиются вводимые значения числа строк и столбцов матрицы
Col=col;
Value=new double*[row]; //конструктор создает двумерный динамический массив
for (int i=0; i<row; i++) Value[i]=new double[col];
}
matrix::matrix(const matrix& m) //копирующий конструктор - создает копию матрицы m
:Row(m.Row),Col(m.Col)
{
Value=new double *[Row];
for (int i=0; i<Row; i++) Value[i]=new double[Col];
for (int i=0; i<Row; i++)
{
for (int j=0; j<Col; j++)
Value[i][j] = m.Value[i][j];
} // значения элементов матрицы будут такими же, как у матрицы m
}
int matrix::GetRow() //функция получает значение числа строк
{
return (Row);
}
int matrix::GetCol() //функция получает значение числа столбцов
{
return (Col);
}
istream &operator>>(istream &istr, matrix &m) // перегрузка оператора ввода матрицы
{
for (int i=0; i<m.GetRow(); i++)
for (int j=0; j<m.GetCol(); j++)
istr>>m(i, j);
return(istr);
}
ostream &operator<<(ostream &ostr, matrix &m) //перегрузка оператора вывода матрицы
{
for (int i=0; i<m.GetRow(); i++)
{
for (int j=0; j<m.GetCol(); j++)
ostr<<m(i,j)<<"\t";
ostr<<"\n";
}
return(ostr);
}
matrix operator+(matrix &m1, matrix &m2) //перегрузка оператора плюс (бинарный)
{
matrix temp(m1.GetRow(),m1.GetCol());
for (int i = 0; i<m1.GetRow(); i++)
for (int j = 0; j<m1.GetCol(); j++)
temp(i,j)=m1(i,j)+m2(i,j);
return(temp);
}
matrix operator-(matrix &m1, matrix &m2) //перегрузка оператора минус (бинарный)
{
matrix temp1(m1.GetRow(),m1.GetCol());
for (int i = 0; i<m1.GetRow(); i++)
for (int j = 0; j<m1.GetCol(); j++)
temp1(i,j)=m1(i,j)-m2(i,j);
return(temp1);
}
double& matrix::operator()(int row, int col)//перегрузка круглых скобок для матрицы.
{ // Если m - матрица, то m(i,j) будет
return (Value[row][col]); //означать i,j-тый элемент матрицы
}
double matrix::operator()(int row, int col) const//перегрузка круглых скобок для матрицы.
{ // Если m - матрица, то m(i,j) будет
return (Value[row][col]); //означать i,j-тый элемент матрицы
}
matrix::~matrix() //деструктор
{
for (int i=0; i<Row; i++)
delete[] Value[i]; //деструктор удаляет из памяти динамический массив, созданный конструктором
delete[] Value;
}
int main()
{
int m,n;
cout<<"enter number of rows and columns of matrices: "; cin>>m>>n;
matrix a(m,n);
matrix b(m,n);
matrix c(m,n);
cout<<"enter matrix A:\n"; cin>>a;
cout<<"enter matrix B:\n"; cin>>b;
c=a+b;
cout<<"sum of two matrices A and B :\n"<<c << endl;
c=a-b;
cout<<"subtraction of two matrices A and B :\n"<<c << endl;
return 0;
}
Виртуальный выделенный сервер (VDS) становится отличным выбором
Надо представить десятичное число в unsigned char и реализовать операции сложениявычитания, умножения и деления
Я написал функцию подсчета ветвей - branches(TNode*&, int)Работает почти исправно, но если ввести несуществующую вершину, то выдает просто значение...
Как вывести в файл значения целочисленных переменных x,y,z (здесь z - количество часов, y - количество минут, x - количество секунд) в формате hh:mm:ss...
Я правильно понимаю, что: Библиотека - это набор функций ? Заголовочный файл - это набор прототипов нужных функций из библиотеки ? Стандартная...