我正在尝试编写一个实现矩阵的小库,并对它们进行一些基本操作。现在我正在尝试实现LU分解。问题是我的程序有时会运行没有问题,有时它会提前终止,而Windows只是说“test.exe已经达到顶峰”。
我正在使用g ++编译以下选项:
g++ "./Lineair Algebra/Matrix.cpp" "./Lineair Algebra/Determinant.cpp" test.cpp -g -lm -std=c++11 -o test.exe
包含文件Determinant.cpp,因为我打算使用分解来计算大小为>的决定因素。 3。
调用分解的代码在test.cpp中: TEST.CPP:
#include "./Lineair Algebra/Matrix.hpp"
#include "./Lineair Algebra/Determinant.hpp"
int main (void)
{
Matrix n (4,4);
Matrix& nRef = n;
n.set(0,0,2);
n.set(0,3,1);
n.set(2,0,-2);
n.set(3,0,4);
n.set(1,1,1);
n.set(2,1,-3);
n.set(3,1,-4);
n.set(1,2,3);
n.set(2,2,-5);
n.set(3,2,4);
n.set(0,3,1);
n.set(1,3,-3);
n.set(2,3,2);
n.set(3,3,6);
Matrix tmp1 (4,4);
Matrix tmp2 (4,4);
Matrix& tmp1Ref = tmp1;
Matrix& tmp2Ref = tmp2;
n.print();
cout << "Decomposing" << endl;
n.LUDecompose(tmp1Ref,tmp2Ref);
cout << "Test.cpp regained control" << endl;
n.print();
tmp1.print();
tmp2.print();
cout << "Done printing, returning 0 from test.cpp" << endl;
return 0;
}
Matrix.hpp:
#ifndef MATRIX_HPP
#define MATRIX_HPP
#include <iostream>
#include <vector>
using namespace std;
typedef vector< vector<double> > Table;
class Matrix
{
private:
Table array;
int rows;
int cols;
public:
Matrix();
Matrix(int r, int c);
Matrix(Table t);
~Matrix(void);
//Matrix (double** dp, size_t r, size_t c);
Matrix operator+ (Matrix m);
Matrix operator+ (double d);
Matrix operator- (Matrix m);
Matrix operator- (double d);
Matrix operator* (Matrix m);
Matrix operator* (double d);
void operator*= (double d);
Matrix operator/ (double d);
void operator/= (double d);
bool operator== (Matrix m);
bool operator!= (Matrix m);
bool isSquare () const;
bool isRow () const;
bool isCol () const;
int getElements () const;
int getRows() const;
int getCols() const;
int getSize () const;
double get(int row, int col) const;
void getSubMatrix (int rowFrom, int colFrom, int rowTo, int colTo, Matrix& dest) const;
void getTable (Table& t) const;
int getRow (int row, Matrix& dest) const;
int getCol (int col, Matrix& dest) const;
void set(int row, int col, double value);
void set (Table& t);
void expand (int r, int c);
int addRows (int row, const Matrix& rrm);
int addCols (int col, const Matrix& rcm);
void gaussEliminate (Matrix& lower, Matrix& upper);
int LUDecompose (Matrix& l, Matrix& u);
int transpose (Matrix& dest);
void print ();
};
#endif
Matrix.cpp大约有600行,所以我会尝试只发布必要的内容:
Matrix.cpp:构造函数和析构函数(仅用于调试)
#include <iostream>
#include <vector>
#include "Matrix.hpp"
using namespace std;
typedef vector< vector<double> > Table;
Matrix::Matrix()
{
array = Table (1, vector <double> (1));
array[0][0] = 0;
}
Matrix::Matrix(int r, int c)
{
array = Table (c, vector <double> (r));
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
this->set(i, j, 0);
}
}
}
Matrix::Matrix(Table t) : array(t) {}
Matrix::~Matrix(void)
{
cout << "Deleting matrix" << endl;
}
Matrix.cpp:LUDecompose方法
int Matrix::LUDecompose (Matrix& refLower, Matrix& refUpper)
{
if (!this->isSquare())
{
cout << "Given matrix is not a square matrix" << endl;
return -1;
}
else
{
double c = 0;
Matrix rowMatrix (1,this->getCols());
Matrix& refRowMatrix = rowMatrix;
refUpper = *this;
for (int i = 1; i < this->getRows(); i++)
{
for (int j = 0; j < i; j++)
{
if (i >= j)
{
refUpper.getRow(j,refRowMatrix);
rowMatrix *= refUpper.get(i,j);
rowMatrix /= refUpper.get(j,j);
rowMatrix *= -1.0;
c = refUpper.get(i,j) / refUpper.get(j,j);
refUpper.addRows(i,refRowMatrix);
refLower.set(i, j, c);
cout << "Leaving if statement" << endl;
}
cout << "Leaving inner for loop" << endl;
}
cout << "Leaving outer for loop" << endl;
}
for (int i = 0; i < this->getRows(); i++)
{
refLower.set(i,i,1);
}
cout << "Returning 0 from LUDecompose" << endl;
return 0;
}
}
现在我知道那里有libs为我做这个但是这不是重点,我只是想在这里学习。 还要记住,我主要是自学成才,所以我的代码可能不符合(某些人的)专业标准。
当我在gdb之外运行此代码时,这是我得到的输出:
Deleting matrix
Deleting matrix
[2 0 0 1 ]
[0 1 3 -3 ]
[-2 -3 -5 2 ]
[4 -4 4 6 ]
Decomposing
Deleting matrix
Leaving if statement
Leaving inner for loop
Leaving outer for loop
Leaving if statement
Leaving inner for loop
Leaving if statement
Leaving inner for loop
Leaving outer for loop
Leaving if statement
Leaving inner for loop
Leaving if statement
Leaving inner for loop
Leaving if statement
Leaving inner for loop
Leaving outer for loop
Returning 0 from LUDecompose
Deleting matrix
Test.cpp regained control
[2 0 0 1 ]
[0 1 3 -3 ]
[-2 -3 -5 2 ]
[4 -4 4 6 ]
[1 0 0 0 ]
[0 1 0 0 ]
[-1 -3 1 0 ]
[2 -4 4 1 ]
[2 0 0 1 ]
[0 1 3 -3 ]
[0 0 4 -6 ]
[0 0 0 16 ]
Done printing, returning 0 from test.cpp
Deleting matrix
Deleting matrix
Deleting matrix
成功运行,或以下表示不成功的运行:
Deleting matrix
Deleting matrix
[2 0 0 1 ]
[0 1 3 -3 ]
[-2 -3 -5 2 ]
[4 -4 4 6 ]
Decomposing
Deleting matrix
Leaving if statement
Leaving inner for loop
Leaving outer for loop
Leaving if statement
Leaving inner for loop
Leaving if statement
Leaving inner for loop
Leaving outer for loop
Leaving if statement
Leaving inner for loop
Leaving if statement
Leaving inner for loop
Leaving if statement
Leaving inner for loop
Leaving outer for loop
Returning 0 from LUDecompose
Deleting matrix
从GDB运行代码时,它总是崩溃,GDB产生以下输出:
[New Thread 1584.0x8b8]
[New Thread 1584.0xdb8]
[New Thread 1584.0x13fc]
[New Thread 1584.0x10b8]
Deleting matrix
Deleting matrix
[2 0 0 1 ]
[0 1 3 -3 ]
[-2 -3 -5 2 ]
[4 -4 4 6 ]
Decomposing
Deleting matrix
Leaving if statement
Leaving inner for loop
Leaving outer for loop
Leaving if statement
Leaving inner for loop
Leaving if statement
Leaving inner for loop
Leaving outer for loop
Leaving if statement
Leaving inner for loop
Leaving if statement
Leaving inner for loop
Leaving if statement
Leaving inner for loop
Leaving outer for loop
Returning 0 from LUDecompose
Deleting matrix
warning: HEAP[test.exe]:
warning: Heap block at 00801188 modified at 00801198 past requested size of 8
Program received signal SIGTRAP, Trace/breakpoint trap.
0x76fdee8b in ?? ()
我在网上查了一下这个错误,我怀疑是关于某些事情超出了范围但是我没有理解为什么。
请温柔,这是我的第一个问题;)
编辑:稍微清理test.cpp,删除未使用的行列式和矩阵
编辑2:我知道我需要调试这个程序。问题是我不明白它为什么会崩溃。当我在gdb中使用bt时,它指向de destructor,并且上面的任何帧都与vector(de)allocator有关。
编辑3:删除=运算符,将构造函数中的[]更改为at()方法。根据要求,这是set方法:
void Matrix::set(int row, int col, double value)
{
array[row][col] = value;
}
void Matrix::set (Table& t)
{
if (t.size() > this->getCols())
{
this->expand(0,t.size() - this->getCols());
}
if (t[0].size() > this->getRows())
{
this->expand(t[0].size() - this->getRows(),0);
}
for (int i = 0; i < t[0].size(); i++)
{
for (int j = 0; j < t.size(); j++)
{
this->set(i,j,t[i][j]);
}
}
}
编辑4:更新构造函数以反映Paul McKenzie的评论
编辑5:我很抱歉没有发布以下功能,我只是认为我的帖子已经足够长了...... 无论如何,你去:
void Matrix::operator*= (double d)
{
for (int i = 0; i < this->getRows(); i++)
{
for (int j = 0; j < this->getCols(); j++)
{
this->set(i, j, this->get(i,j) * d);
}
}
}
void Matrix::operator/= (double d)
{
if (d != 0)
{
for (int i = 0; i < this->getRows(); i++)
{
for (int j = 0; j < this->getCols(); j++)
{
this->set(i, j, this->get(i,j) / d);
}
}
}
else
{
cout << "Can not divide by zero" << endl;
}
}
bool Matrix::isSquare () const
{
if (this->getRows() == this->getCols())
{
return true;
}
else
{
return false;
}
}
int Matrix::getRows() const
{
return this->array.at(0).size();
}
int Matrix::getCols() const
{
return this->array.size();
}
double Matrix::get(int row, int col) const
{
if ((row < this->getRows()) && (col < this->getCols()))
{
return array[row][col];
}
else
{
cout << "Couldn't get (" << row << "," << col <<"), element is out of bounds. dim = " << this->getRows() << " x " << this->getCols() << endl;
return -1;
}
}
int Matrix::getRow (int row, Matrix& dest) const
{
if (!dest.isRow())
{
cout << "Destination matrix is not a row matrix" << endl;
return -1;
}
else
{
for (int i = 0; i < this->getCols(); i++)
{
dest.set(0, i, this->get(row,i));
}
return 0;
}
}
int Matrix::addRows (int row, const Matrix& rrm)
{
if (!rrm.isRow())
{
cout << "Specified matrix is not a row matrix." << endl;
return -1;
}
else if (rrm.getCols() != this->getCols())
{
cout << "Matrix dimensions do not match." << endl;
return -1;
}
else if (row >= this->getRows())
{
cout << "Given row number exceeds amount of rows in matrix." << endl;
return -1;
}
else
{
for (int i = 0; i < rrm.getCols(); i++)
{
this->set(row, i, this->get(row, i) + rrm.get(0,i));
}
return 0;
}
}
编辑6:我通过VS的调试器运行了我的代码,这让我在Matrix::set (int row, int col, double value)
处超出范围异常。奇怪的是,我已经更新了方法来进行范围检查。调用堆栈如下所示:
Matrix.cpp :: set(int row,int col,double value)@ line 415(array.at(row).at(col) = value;
)
Matrix.cpp :: Matrix(int r,int c)@第25行(内部for循环的右括号)
Matrix.cpp :: LUDecompose(Matrix&amp; refLower,Matrix&amp; refUpper)@ line 526(Matrix rowMatrix(1, this->getCols());
)
Test.cpp :: Main @ line 35(cout << "Test.cpp regained control" << endl;
)
这是目前的方法:
void Matrix::set(int row, int col, double value)
{
if ((row < this->getRows()) && (col < this->getCols()))
{
array.at(row).at(col) = value;
}
else
{
cout << "Trying to assign to (" << row << "," << col << "): Out of bounds, dim = " << this->getRows() << " x " << this->getCols() << endl;
}
}
编辑7: 在VS中稍微摆弄后,我能够修复代码。我进行了多次编辑,但我很确定引起上述异常的那个是array.at(n)返回第n个COLUMN(而不是第n行),这可以在我的代码中看到)和array.at(n).at(m)返回位置(m,n)处的元素(其中m是第m行,n是第n列) 感谢大家帮助我,这里是固定集方法的副本:
void Matrix::set(int row, int col, double value)
{
if ((row < this->getRows()) && (col < this->getCols()))
{
array.at(col).at(row) = value;
}
else
{
cout << "Trying to assign to (" << row << "," << col << "): Out of bounds, dim = " << this->getRows() << " x " << this->getCols() << endl;
}
}
答案 0 :(得分:0)
程序崩溃的原因之一是你可能会删除一些东西检查你的程序或在IDE中编译你的程序
答案 1 :(得分:0)
在调试程序的调试版本时,编译器会在代码中插入额外的运行时检查,对您来说是不可见的。这些检查可以检测您是否释放内存两次,使用未初始化的变量,超出分配的内存块等。这是为了帮助您,如果您的程序正在做一些非法的事情,可以检测不到。发行版本中不存在这些检查,因此永远不会显示错误/警告,但程序会随机崩溃和/或行为异常。
在这种情况下,您有此警告:
警告:堆积在00801188处修改为00801198,请求大小为8
运行时检查检测到您在内存位置00801188分配了8个字节,并且从此位置开始写入超过8个字节,一直到00801198。
这个几乎总是指出在循环中使用数组时出现问题。这是一个例子:
假设您分配了10个整数的数组:import {
it,
describe,
expect
} from 'angular2/testing';
现在您想要为每个数组成员写一些值:
int my[10];
这会导致像你这样的确切错误。由于条件为for ( int i=0; i<=10; i++ ) {
my[i]=some_calculation();
}
(程序员不小心,应该是i<=10
或i<10
),写入的最后一个成员是i<=9
,第11个数组成员,但是你只为10 分配了空间。因此,在您的第10个成员之后的一些其他内存被覆盖,导致程序中出现不可预测的行为。
最后,检查所有为数组成员写入值的循环,并确保不要写入比分配的更多的数组元素。