我撰寫了以下代碼來執行簡單的矩陣乘法。
#include <stdio.h>
void op2(float *a_vec, int m, int n, int p, float *b_vec, float *c_vec){
float (*a)[n] = (float(*)[n]) a_vec;
float (*b)[p] = (float(*)[p]) b_vec;
float (*c)[p] = (float(*)[p]) c_vec;
int i, j, k;
for (i = 0; i<m; i ){
for(j=0; j<p; j ){
for(k=0; k<n; k ){
c[i][j] = a[i][k] * b[k][j];
}
printf("%.1f ", c[i][j]);
}
printf("\n");
}
}
int main(void){
float *aVec;
float *bVec;
float *cVec;
int m = 2;
int n = 3;
int p = 2;
float a[6] = {
1,3,1,
2,2,2
};
aVec = &a[0];
float b[6] = {
1,3,
1,2,
2,2
};
bVec = &b[0];
float c[4];
cVec = &c[0];
op2(aVec, m, n, p, bVec, cVec);
}
結果向量(列印到輸出)應該是 6.0 11.0 8.0 14.0
它是什么......大多數時候。
然而,有時并非如此。有時陣列的第一個值會不正確。最常見的是 5.7 或 5.8 5.8 11.0 8.0 14.0
我的問題是,我在這里做什么導致這種不一致?我對 C 很陌生,我最好的猜測是,也許我錯過了與陣列索引有關的一些東西,也許我跑過了陣列的末尾?但是我看不出它會如何不一致地發生,因為它具有相同的輸入,所以也許我缺少指標的東西?
嘗試過:在回圈外宣告陣列變數,更改輸入陣列中的值。
uj5u.com熱心網友回復:
c[i][j] = a[i][k] * b[k][j];只有在矩陣初始化為零時,才能進入回圈c。但是,c陣列float c[4];inmain宣告時沒有初始化器,因此它包含垃圾,當您添加乘法的結果時會產生更多垃圾。
valgrind記憶體檢查工具發現了這個錯誤。像這樣的工具對于 C 除錯來說是非常寶貴的,并且應該成為您在遇到錯誤時首先嘗試的事情之一。AddressSanitizer (-fsanitize=address) 和 UBSan (-fsanitize=undefined) 都可以在 GCC 和 clang 中使用,它們也很不錯,但是他們碰巧沒有發現這個 bug。
這個特殊問題可以通過定義來解決float c[4] = {0.0};。(一旦你初始化了一個陣列的至少一個元素,其余的都會自動初始化為零。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/532806.html
標籤:C指针矩阵
