为什么我的C++程序不能让我获得我之前分配的值而不是随机双精度?



我一直在做一个处理矩阵并用它进行操作的项目。我这样做是为了学习内存管理和理解面向对象编程。所以,首先,我不想使用矩阵库。

在我的课上,我为Matrix类做了一个构造函数,它有三个参数:int row_number, int column_number, string inside_expression。inside_expression是一种创建矩阵并在其中赋值的方法。使用inside_eexpression的模板看起来像MatLab,但没有处理空格:

Ex。maths::Matrix matrix1(3, 3, "1,5.7,6;23,4,0;5,5,2;");

顺便说一下,它不需要是平方矩阵。数学是名称空间的名称。

所以,就目前而言,一切都很完美。程序制作了一个带有替身的多维数组,之后,它为控制台提供了一个矩阵的外观,用于调试目的。我正在测试每一个可能的给定代码,我看到了一个错误的输出。如果矩阵上最后一列和最后一行的最后一个元素为零,它会分配_matrix[last_row][last_col] = 0,但在分配之后,如果我想打印值,它会给我一个随机的双精度。

为什么会这样?我将把我的构造函数复制到这里。谢谢大家。:(祝你今天愉快。


Matrix::Matrix(int _row, int _column, std::string _inside) {
//std::cout << _inside << "n";
row = _row - 1;
col = _column - 1;
// Matrix Creation with Arrays
_matrix = new double*[row];
for (int index = 0; index <= row; index++) {
_matrix[index] = new double[col];
}
/* Template for creating matrix: "1,5.4,6,7;8.7,9,7,3;15,4,7,2;"
Because of that we need to find their positions on string
and store them as two dimensional array.
[first;    ,   sec;   ,    third;]
[1,          [8.7,          [15,
5.4,             9,            4,
6,             7,            7,
7]             3]            2]
*/
int row_cursor = 0; // For row value.
while (true) {
int pos = _inside.find(";");
//std::cout << "tpos: " << pos << "n";
// If there's no ; character, it'll break the while loop.
if (pos == std::string::npos) {
if (row_cursor == 0) {std::cerr << "Given matrix is invalid type!";}
break;
}
// Finding commas and inserting numbers to matrix.
for (int index = 0; index <= col; index++) {
int item_pos = _inside.substr(0, pos).find(",");
//std::cout << "ttitem_pos: " << item_pos << "n";
// If can't find comma (when x;y,z,f; situation happens)
if (item_pos == -1 || item_pos >= pos) {
int _OLD_POS = pos;
pos = _inside.find(";");
//std::cout << "ttnew pos: " << pos << "n";
_matrix[row_cursor][index] = std::stod(_inside.substr(0, pos));
//std::cout << "ttmsubstr val: " << _inside.substr(0, pos) << "t";
//std::cout << "matix value: " << _matrix[row_cursor][index] << "n";
_inside.erase(0, pos + 1);
//std::cout << "tterased _inside: " << _inside << "n";
pos = _OLD_POS - _inside.substr(0, pos).length();
//std::cout << "t-> pos: " << pos << "n";
} else {
_matrix[row_cursor][index] = std::stod(_inside.substr(0, item_pos));
//std::cout << "ttmsubstr val: " << _inside.substr(0, item_pos) << "t";
_inside.erase(0, item_pos + 1);
//std::cout << "tterased _inside: " << _inside << "n";
pos = pos - _inside.substr(0, item_pos).length();
//std::cout << "t-> pos: " << pos << "n";
}
}
row_cursor++;
}
// To see matrix:
for (int index = 0; index <= row; index++) {
for (int jindex = 0; jindex <= col; jindex++) {
std::cout << _matrix[index][jindex] << " ";
}
std::cout << "n";
}

关于代码的注意:我评论了控制台打印,以免打扰您。

具有row元素的数组的最后一个有效索引是row-1。在这里,您创建了一个包含row元素的数组,循环的最后一次迭代尝试访问_matrix[row],但这不是数组的一部分。

_matrix = new double*[row];
for (int index = 0; index <= row; index++) {
_matrix[index] = new double[col];
}

越界访问数组会调用未定义的行为。执行您的代码,任何事情或什么都可能发生。

常见的惯例是使用基于0的索引和半开放区间,即循环应该是

for (size_t index = 0; index < row; ++index)
// ^----------------- !!!

PS:使用基于0或基于1的索引各有利弊。公约的重要之处不在于它没有同样有效的替代方案,而在于你始终如一地应用它。不要混合使用基于0和1的索引。这将是一片混乱。

最新更新