我确信这很简单,但我无法设计一个帮助我解决问题的搜索查询。
我几乎倾向于认为这是Windows命令提示符中的一个错误,除了之前我从未见过它,直到我开始使用异常,当且仅当我使用异常时才会发生异常:: what ()。
这是一个家庭作业,该程序应该计算一系列给定的问题并显示答案。所有问题都是类似的(矩阵/向量算法),唯一导致问题的是有意设计产生错误的问题,因为这是唯一的时间例外:: what()。
这是一个令人不快的问题:
(顺便说一句,任意放置这些都可以 问题进入块,以便对象超出范围,并在下一个问题之前调用析构函数,就像我已经完成的那样?)
{ // Problem #9
Vector v1(5);
Matrix m1(3, 3, 1);
try {
v1.set(1, -2);
v1.set(2, -1);
v1.set(3, 4);
v1.set(4, 9);
v1.set(5, 3);
m1.set(1, 1, 12);
m1.set(1, 2, 36);
m1.set(1, 3, -7);
m1.set(2, 1, 4);
m1.set(2, 3, 11);
m1.set(3, 1, 7);
m1.set(3, 2, -5);
m1.set(3, 3, -2);
Vector * ans9 = product(m1, v1);
cout << "Answer to problem 9:" << endl;
ans9->print();
delete ans9;
}
catch(exception & ex) {
cout << "Exception in problem 9: " << ex.what() << endl;
}
} // End problem 9
cout << endl << endl;
Matrix类及其构造函数没什么特别的,代码不会抛出任何异常,所以我只会分享有问题的product()函数:
Vector * product(Matrix &m, Vector &v) {
unsigned int vLength = v.getLength(), mRows = m.getRows(), mCols = m.getCols();
if ( mCols != vLength ) {
throw std::logic_error("matrix/vector product impossible (size mismatch)!");
}
Vector * vprod = new Vector(mRows);
for (unsigned int i = 1; i <= mRows; ++i) {
double value = 0;
for (unsigned int j = 1; j <= vLength; ++j) {
value += (m.get(i, j)) * (v.get(j));
}
vprod->set(i, value);
}
return vprod;
}
这是我得到的输出类型的一个例子:
screenshot http://img827.imageshack.us/img827/7328/wtfuz.png
我离开了!在那里你可以看到它只是打印那个列上的最后一个字符,直到那里明确地印有其他字符。
那么,到底发生了什么?我认为它可能与字符串终止有关,但也许这只是因为我过去对C有太多的乐趣。
编辑:人们要求提供可编辑的代码段,我能做的最好的就是228行。这是:
#include <iostream>
#include <iomanip>
#include <cstdlib>
using std::cout;
using std::endl;
using std::exception;
class Vector {
private:
unsigned int length;
double *elements;
public:
Vector(unsigned int desiredLength);
~Vector();
//void dDestroy(Vector &v);
unsigned int getLength();
void set(unsigned int position, double value);
double get(unsigned int position);
void print();
};
Vector::Vector(unsigned int desiredLength) {
length = desiredLength;
elements = new double[length];
for (unsigned int i = 0; i < length; ++i) {
elements[i] = 0;
}
}
Vector::~Vector() {
delete[] elements;
}
unsigned int Vector::getLength() {
return length;
}
void Vector::set(unsigned int position, double value) {
if (position > length || position <= 0) {
throw std::logic_error("vector set failed (out of range)");
}
--position;
elements[position] = value;
}
double Vector::get(unsigned int position) {
if (position > length || position <= 0) {
throw std::logic_error("vector get failed (out of range)");
}
--position;
return elements[position];
}
void Vector::print() {
std::cout << "[ ";
for (unsigned int i=0; i < length; ++i) {
std::cout << elements[i] << " " ;
}
std::cout << "]";
}
class Matrix {
private:
unsigned int rows, cols;
double **elements;
public:
Matrix(unsigned int desiredRows, unsigned int desiredCols, double defaultValue);
~Matrix();
unsigned int getRows();
unsigned int getCols();
void set(unsigned int i, unsigned int j, double value);
double get(unsigned int i, unsigned int j);
void print();
};
Matrix::Matrix(unsigned int desiredRows, unsigned int desiredCols, double defaultValue) {
rows = desiredRows, cols = desiredCols;
// Create
elements = new double*[rows];
for (unsigned int i = 0; i < rows; ++i) {
elements[i] = new double[cols];
}
// Initialize
for (unsigned int i = 0; i < rows; ++i) {
for (unsigned int j = 0; j < cols; ++j) {
elements[i][j] = defaultValue;
}
}
}
Matrix::~Matrix() {
for (unsigned int i = 0; i < rows; ++i) {
delete[] elements[i];
}
delete[] elements;
}
unsigned int Matrix::getRows() {
return rows;
}
unsigned int Matrix::getCols() {
return cols;
}
void Matrix::set(unsigned int i, unsigned int j, double value) {
if (i > rows || j > cols) {
throw std::logic_error("matrix set failed (out of range).");
}
--i, --j;
elements[i][j] = value;
}
double Matrix::get(unsigned int i, unsigned int j) {
if (i > rows || j > cols || i <= 0 || j <= 0) {
throw std::logic_error("matrix get failed (out of range).");
}
--i, --j;
return elements[i][j];
}
void Matrix::print() {
// TODO it would be nice to format based on maximum digits in any value
for (unsigned int i = 0; i < rows; ++i) {
std::cout << "[ ";
for (unsigned int j = 0; j < cols; ++j) {
std::cout << std::setprecision(2) << elements[i][j] << " ";
}
std::cout << "]\n";
}
}
Vector * dot(Vector &v1, Vector &v2) {
if (v1.getLength() != v2.getLength() ) {
throw std::logic_error("dot product impossible (length mismatch)");
}
double result = 0;
for (unsigned int i = 1; i <= v1.getLength(); ++i) {
result += (v1.get(i) * v2.get(i));
}
Vector * vdot = new Vector(1);
vdot->set(1, result);
return vdot;
}
Vector * product(Matrix &m, Vector &v) {
unsigned int vLength = v.getLength(), mRows = m.getRows(), mCols = m.getCols();
if ( mCols != vLength ) {
throw std::logic_error("matrix/vector product impossible (size mismatch)");
}
Vector * vprod = new Vector(mRows);
for (unsigned int i = 1; i <= mRows; ++i) {
double value = 0;
for (unsigned int j = 1; j <= vLength; ++j) {
value += (m.get(i, j)) * (v.get(j));
}
vprod->set(i, value);
}
return vprod;
}
Vector * dot(Vector &v1, Vector &v2);
Vector * product(Matrix &m, Vector &v);
int main() {
cout << endl;
{ // Problem #1
Vector v1(3), v2(3);
try {
v1.set(1, 2);
v1.set(2, 1);
v1.set(3, 3);
v2.set(1, 0);
v2.set(2, 4);
v2.set(3, -9);
Vector * ans1 = dot(v1, v2);
cout << "Answer to problem 1:" << endl;
ans1->print();
delete ans1;
}
catch(const exception & ex) {
cout << "Exception in problem 1: " << ex.what() << endl;
}
} // End problem 1
cout << endl << endl;
{ // Problem #2
Vector v1(2), v2(3);
try {
v1.set(1, 12);
v1.set(2, 1);
v2.set(1, 3);
v2.set(2, -1);
v2.set(3, 5);
Vector * ans2 = dot(v1, v2);
cout << "Answer to problem 2:" << endl;
ans2->print();
delete ans2;
}
catch(const exception & ex) {
cout << "Exception in problem 2: " << ex.what() << endl;
}
} // End problem 2
cout << endl << endl;
}
答案 0 :(得分:1)
好的,评论有点慌张,以下内容对于评论有点明确,所以请原谅以下不完全答案的风格。
因为额外的“!”在程序已经退出之后,也有可能与你的应用程序有关。它可能是一个错误的显示驱动程序,或客户端服务器运行时子系统/进程(csrss.exe)或控制台Windows主机(conhost.exe)的一些问题,它们在您运行控制台应用程序时提供窗口。 此外,如果截图不是误导性的,那么看起来像超级字符(特别是“问题6”中的右括号可见)甚至不能完全重复,而只是部分重复。即这个角色以某种方式被“削减”。
无论如何,您可以尝试进一步调查问题:
如果您实际上没有抛出异常,也会发生这种情况,例如
std :: logic_error err(“blah”); std :: cout&lt;&lt; err.what()&lt;&lt;的std :: ENDL;
您可以将程序更改为使用stdio而不是iostream吗?它是否仍然会发生。
尝试将程序的输出重定向到文件(例如“myapp.exe&gt; foo.txt”)。该文件是否还包含额外的“!”。
我在完全不同的情况下看到了这种行为。
示例:
printf("12345678901234567890\r"); /* carriage return, but no linefeed */
printf("ABCDEFGHIJ\n");
这应输出:
ABCDEFGHIJ1234567890
但是,在我的代码中,我没有看到类似的内容(iostreams与stdio相关)。
答案 1 :(得分:0)
它让我担心你会遇到'异常&amp;'而不是'const exception&amp;'。 'ex'实际上可能引用已经被销毁的对象,因此what()方法返回垃圾。您必须确保catch-handler中的'ex'参数引用最初抛出的对象的有效副本。