C++类中数组赋值方法及Matrix类输出异常问题排查
你的Matrix类错误分析
首先看你的代码里最关键的两个核心错误,直接导致了矩阵元素覆盖和打印异常:
1. 动态内存分配错误
你写的matr = new double[a, b];用到了逗号运算符——C++里逗号运算符会先计算左侧表达式(这里是a)然后直接丢弃结果,最终返回右侧的b值。所以你实际上只分配了b个double的内存空间,而不是a*b个!对于2×2的矩阵来说,这就意味着你只有2个元素的存储位置,根本存不下4个矩阵值。
正确的二维矩阵动态分配应该把二维结构转成一维数组,计算总元素数:
matr = new double[a * b];
2. 元素访问错误
同样的问题出现在at、setPos以及直接访问matr[r, c]的地方:r, c还是逗号运算符,会直接返回c的值。这就导致不管行号r是0还是1,你访问的都是matr[c]的位置:
matr[0,0]和matr[1,0]都会访问matr[0]matr[0,1]和matr[1,1]都会访问matr[1]
所以你在randomize方法中,(1,0)的随机值会直接覆盖(0,0)的,(1,1)覆盖(0,1)的,打印时自然只会看到后面两个值重复出现,前面的元素被完全覆盖了。
正确的二维转一维索引计算应该是行优先的公式:
double &at(int pos1, int pos2) { return matr[pos1 * cols + pos2]; }; void setPos(int pos1, int pos2, double value) { matr[pos1 * cols + pos2] = value; };
额外提醒:避免内存泄漏
你当前的代码没有析构函数,会导致动态分配的内存无法释放,一定要添加:
~Matrix() { delete[] matr; }
另外,记得在程序开头调用srand(time(nullptr));初始化随机数生成器,不然每次运行生成的随机数序列都是一样的。
C++类中数组赋值的正确方式
根据数组类型的不同,赋值方式也有区别:
1. 静态数组(编译期确定大小)
如果是类内的固定大小数组,可以用以下几种方式赋值:
#include <algorithm> class MyClass { private: int arr[3]; public: MyClass() { // 方式1:逐个赋值 arr[0] = 1; arr[1] = 2; arr[2] = 3; // 方式2:用std::copy批量赋值 int temp[] = {1,2,3}; std::copy(std::begin(temp), std::end(temp), std::begin(arr)); } // C++11及以后,还可以直接在初始化列表里赋值 // MyClass() : arr{1,2,3} {} };
更推荐用std::array代替原生静态数组,类型更安全,操作更便捷:
#include <array> class MyClass { private: std::array<int,3> arr; public: MyClass() : arr{1,2,3} {} // 直接初始化 };
2. 动态数组(运行期确定大小)
就是你代码里的场景,需要用new[]分配内存,再通过循环或批量拷贝赋值:
class MyClass { private: int* arr; int size; public: MyClass(int s) : size(s) { arr = new int[s]; // 方式1:循环逐个赋值 for(int i=0; i<size; i++) { arr[i] = i; } // 方式2:有数据源时用std::copy // int temp[] = {1,2,3}; // std::copy(temp, temp+size, arr); } ~MyClass() { delete[] arr; // 必须手动释放内存 } };
如果是二维动态数组,更推荐用std::vector<std::vector<T>>,不用手动管理内存,代码更简洁:
#include <vector> class Matrix { private: std::vector<std::vector<double>> matr; public: Matrix(int rows, int cols) : matr(rows, std::vector<double>(cols, 0.0)) {} void randomize() { for(auto& row : matr) { for(auto& elem : row) { elem = double(rand()) / (RAND_MAX + 1.0); } } } };
内容的提问来源于stack exchange,提问作者Matt Ward

