我正在撰寫一個代碼來計算給定矩陣的逆矩陣,問題是,我需要將其包含在其他進行統計擬合的代碼中,所以我需要一個接收矩陣大小的函式(矩陣是方陣)和矩陣本身并回傳他的逆,我找到了一些關于語法的東西,然后有了這個(Gauss-Jordan)
float* inv(int n, float *A)
{
float* I = 0;//*
float aux;
float pivote;
for(int i = 0; i<n; i ){
for(int j = 0; j<n; j ){
if(i == j)
{
*(I i*n j) = 1.0; //*
}
else {
*(I i*n j) = 0.0;
}
}
}
for(int i = 0; i<n; i )
{
pivote = *(A i*n i);
for(int k = 0; k<n; k )
{
*(A i*n k) = *(A i*n k)/pivote;//*
*(I i*n k) = *(I i*n k)/pivote;//*
}
for(int j = 0; j<n; j )
{
if(i!=j)
{
aux = *(A j*n i);//*
for(int k = 0; k<n;k )
{
*(A j*n k)=*(A j*n k)-aux**(A i*n k);//*
*(I j*n k)=*(I j*n k)-aux**(I i*n k);//*
}
}
}
}
return I;//*
}
我放在那里的地方//*是我有疑問的地方,語法是否正確?宣告中,回報中應該有其他東西,而不僅僅是I?編譯時出現分段錯誤,遵循 Taekahn 建議,使用消毒劑進行g -fsanitize=address -fsanitize=undefined -fsanitize=leak inverse.cpp編譯
inverse.cpp:148:28: runtime error: store to null pointer of type 'float'
AddressSanitizer:DEADLYSIGNAL
=================================================================
==11993==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000040338c bp 0x7ffdd6a14510 sp 0x7ffdd6a144b0 T0)
==11993==The signal is caused by a WRITE memory access.
==11993==Hint: address points to the zero page.
#0 0x40338b in inv(int, float*) (/home/live/med_elect/a.out 0x40338b)
#1 0x402f30 in main (/home/live/med_elect/a.out 0x402f30)
#2 0x7f90ffed9e5a in __libc_start_main (/lib64/libc.so.6 0x23e5a)
#3 0x402289 in _start (/home/live/med_elect/a.out 0x402289)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/home/live/med_elect/a.out 0x40338b) in inv(int, float*)
==11993==ABORTING
如果你能幫助我,我真的很感激,非常感謝你,非常感謝你在評論中的反饋,我是新來的問題。
更新:感謝 nasy 的回答,重要的是要注意許多人提到了矢量方法,因此,對于閱讀本文的任何人,請查看評論并更好地嘗試矢量方法。
uj5u.com熱心網友回復:
在您的第二個功能中,您有float *I = 0. 稍后,您嘗試寫入此陣列但尚未分配它。您索引矩陣的方式是扁平化方法,因此您必須撰寫float *I = new float[n*n]. 當然,有不同的方法,如評論中提到的使用動態 2D 陣列、2D 向量等。
uj5u.com熱心網友回復:
問題是指標I不指向任何物件,你有以下陳述句:
*(I i*n j) = 1.0; //undefined behavior
上面的陳述句導致未定義的行為。想象一下當i和j都0在第一次迭代中會發生什么。然后你取消參考I它不指向任何float物件,因此這是未定義的行為。
未定義的行為意味著任何1都可能發生,包括但不限于給出預期輸出的程式。但永遠不要依賴(或基于)具有未定義行為的程式的輸出。該程式可能會崩潰。
所以你看到的輸出(也許看到)是未定義行為的結果。正如我所說,不要依賴具有 UB 的程式的輸出。該程式可能會在您的情況下發生崩潰。
因此,使程式正確的第一步是洗掉 UB。只有這樣,您才能開始推理程式的輸出。
此外,它會比使用和std::vector進行手動記憶體管理更好。newdelete
1對于未定義行為的技術上更準確的定義,請參見此處提到:對程式的行為沒有限制。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/464863.html
上一篇:Python中的計算分歧
