我正在编写2个矩阵的矩阵乘法代码,大小为n1,n2
和n2,n3
。
这就是我所尝试的:
#include <climits>
#include <iostream>
using namespace std;
int main() {
int n1 = 3;
int n2 = 3;
int n3 = 3;
int arr1[n1][n2] = {
{1, 2, 3},
{5, 6, 7},
{9, 10, 11}
};
int arr2[n2][n3] = {
{2, 0, 0},
{0, 2, 0},
{0, 0, 2}
};
int res[n1][n3];
for (int c = 0; c < n3; c++) {
for (int r = 0; r < n1; r++) {
for (int i = 0; i < n2; i++) {
res[r][c] += arr1[r][i] * arr2[i][c]; // This is the main part
}
}
}
for (int i = 0; i < n1; i++) {
for (int j = 0; j < n3; j++) {
cout << res[i][j] << ' ';
}
cout << endl;
}
return 0;
}
输出为:
6422058 1877910233 1878006934
1878000406 20 7022734
7022746 68 22
然后,我尝试更改具有+=
的行:
int res[n1][n3];
for(int c = 0; c < n3; c++){
for(int r = 0; r < n1; r++){
int val = 0;
for(int i = 0; i < n2; i++){
val += arr1[r][i] * arr2[i][c]; // Here I used new variable val
}
res[r][c] = val;
}
}
问题消失了。输出:
2 4 6
10 12 14
18 20 22
为什么这解决了问题?
1条答案
按热度按时间kmpatx3s1#
问题是,上线了:
res
中的所有内存都是不确定的,而不是零。这就是为什么打印出如此荒谬和巨大的数值。这是代码中“未定义行为”的症状。这就修复了它,因为您从
val = 0
开始,然后添加到它,并将结果写入res[r][c]
,所以这里没有未定义的行为。但是,您也可以只写:...在顶部,这将初始化
res
中的所有元素为零。所有这些都做同样的事情。关于VLA的说明
所有数组都是Variable Length Arrays (VLAs),这在C++中是不允许的。您必须将其大小设置为
constexpr
,或至少const
才能解决此问题:您的代码只会编译,因为编译器支持将VLA作为非标准扩展。