SPOJ平台矩阵运算代码出现SIGSEGV错误,求问题排查与解决
矩阵转置乘积代码的SIGSEGV错误排查
任务要求
给定m行n列的整数矩阵X(m、n≤100),编写程序计算X的转置与X的乘积(Xᵀ * X)。输入第一行为矩阵行数m∈[1;100],第二列为列数n∈[1;100],后续m行每行含n个[-100;100]的整数作为矩阵元素。
提交的代码
#include <iostream> #include <vector> using namespace std; int main() { int m, n; cin >> m >> n; vector<vector<int>> X(m, vector<int> (n)); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { cin >> X[i][j]; } } vector<vector<int>> Xtransposed(n, vector<int> (m)); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { Xtransposed[j][i] = X[i][j]; } } vector<vector<int>> result(m, vector<int> (m)); for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { for (int k = 0; k < n; k++) { result[i][j] += Xtransposed[i][k] * X[k][j]; } } } for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { cout << result[i][j] << " "; } cout << endl; } return 0; }
错误原因分析
SIGSEGV错误源于内存越界访问,核心问题是对矩阵乘积的维度理解错误:
- 原矩阵X是
m×n,其转置Xᵀ是n×m - 矩阵乘法Xᵀ * X的结果维度应为
n×n(前一个矩阵的行数 × 后一个矩阵的列数) - 你错误地将结果矩阵
result定义为m×m,且乘法循环的i、j范围遍历到m-1:- 当
n < m时,Xᵀ只有n行,循环中访问Xtransposed[i][k](i从0到m-1)会超出Xᵀ的行数范围,触发内存访问错误。
- 当
修正后的代码
#include <iostream> #include <vector> using namespace std; int main() { int m, n; cin >> m >> n; vector<vector<int>> X(m, vector<int>(n)); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { cin >> X[i][j]; } } vector<vector<int>> Xtransposed(n, vector<int>(m)); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { Xtransposed[j][i] = X[i][j]; } } // 修正结果矩阵维度为n×n,显式初始化0避免不确定行为 vector<vector<int>> result(n, vector<int>(n, 0)); // 修正循环范围:i和j遍历n行n列 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { // 点积计算:Xᵀ的第i行与X的第j列相乘求和 for (int k = 0; k < m; k++) { result[i][j] += Xtransposed[i][k] * X[k][j]; } } } // 输出n×n的结果矩阵 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << result[i][j] << " "; } cout << endl; } return 0; }
额外优化
可以省略转置矩阵的创建,直接用原矩阵计算Xᵀ*X的元素(因为Xᵀ[i][k] = X[k][i]),节省内存开销:
// 省略转置矩阵的创建,直接计算结果 vector<vector<int>> result(n, vector<int>(n, 0)); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < m; k++) { result[i][j] += X[k][i] * X[k][j]; } } }
内容的提问来源于stack exchange,提问作者Sadharvseter
相关产品推荐
相关产品推荐

