前提・実現したいこと
C言語を使って数値計算を行っており、プログラムのバグを見つけられず困っています。
バグの内容は
●同じプログラムを実行しても、計算機ごとに結果が違う
●-O0オプションをつける,つけないで結果が違う
(訂正:iccの17.0.1を用いた場合に,この現象が生じます.
gccの8.2.0を用いた場合はこの現象は起きませんでした.)
●特定の箇所にprintfを入れると違っていたはずの結果が一致する.
という感じです.
valgrind等のデバッグツールでメモリリークの検査は行いましたが,
検出されませんでした
###質問
バグを見つける為に元々のプログラムを削り,小さいプログラムを作成しました.
間違っている点がありましたら教えてください.
(このプログラムでも上記のバグが検出されました)
プログラムの内容は、ザックリ言うと配列skから配列grを計算する物です.
(元のプログラムを削ったものなので,
何でこんなものを計算したいのか意味不明でしょうが,
許してください)
該当のソースコード
#include<stdio.h> #include<math.h> #include<stdlib.h> #define dx (0.5) #define Nmeas 2 #define Lx 128 int main(void){ int e=0,i=0,j=0,k=0; double r=0,l=0; double ***sk,**gr; sk=(double***)calloc(Lx,sizeof(double**)); for(i=0;i<Lx;i++){ sk[i]=(double**)calloc(Lx,sizeof(double*)); } for(i=0;i<Lx;i++){ for(j=0;j<Lx;j++){ sk[i][j]=(double*)calloc(Nmeas,sizeof(double)); } } if(sk==NULL){ printf("sk_dame\n"); exit(EXIT_FAILURE); } //skを格納 for(k=0;k<Nmeas;k++){ for(i=0;i<Lx;i++){ for(j=0;j<Lx;j++){ sk[i][j][k]=i*(j+1); } } } // gr=(double**)calloc(Lx,sizeof(double*)); for(i=0;i<Lx;i++){ gr[i]=(double*)calloc(Nmeas,sizeof(double)); } if(gr==NULL){ printf("gr_dame\n"); exit(EXIT_FAILURE); } for(e=0;e<Nmeas;e++){ for(k=0;k<Lx;k++){ r=dx*k; //-- for(i=0;i<Lx;i++){ for(j=0;j<Lx;j++){ if(i<=Lx/2-1){ if(j<=Lx/2-1){ l=sqrt(i*i*dx*dx+j*j*dx*dx); } else{ l=sqrt((Lx-i)*(Lx-i)*dx*dx+(Lx-j)*(Lx-j)*dx*dx); } } else{ if(j<=Lx/2-1){ l=sqrt(i*i*dx*dx+j*j*dx*dx); } else{ l=sqrt((Lx-i)*(Lx-i)*dx*dx+(Lx-j)*(Lx-j)*dx*dx); } } if(r<=l&&l<r+dx){ gr[k][e]=gr[k][e]+sk[i][j][e]; //ここにprintfすると結果が一致する } } } //----- } } for(k=0;k<Nmeas;k++){ for(i=0;i<Lx;i++){ r=dx*i; printf("%d %f %0.10f \n",k,i*dx,gr[i][k]); } } for(i=0;i<Lx;i++){ free(gr[i]); } free(gr); for(i=0;i<Lx;i++){ for(j=0;j<Lx;j++){ free(sk[i][j]); } } for(i=0;i<Lx;i++){ free(sk[i]); } free(sk); return 0; }
計算結果
文字数がオーバーしてしまうので,最後の方だけ載せます
(左がiccのオプションなし,右がオプションありです.gccではオプションに寄らず右の結果になりました)
1 30.000000 33477799.0000000000 | 1 30.000000 873054.0000000000 1 30.500000 34425182.0000000000 | 1 30.500000 854069.0000000000 1 31.000000 34212931.0000000000 | 1 31.000000 855826.0000000000 1 31.500000 35155964.0000000000 | 1 31.500000 865433.0000000000 1 32.000000 34910260.0000000000 | 1 32.000000 826290.0000000000 1 32.500000 35211832.0000000000 | 1 32.500000 824195.0000000000 1 33.000000 35450545.0000000000 | 1 33.000000 707294.0000000000 1 33.500000 35677466.0000000000 | 1 33.500000 728292.0000000000 1 34.000000 35906161.0000000000 | 1 34.000000 738308.0000000000 1 34.500000 36078876.0000000000 | 1 34.500000 647620.0000000000 1 35.000000 36247586.0000000000 | 1 35.000000 679681.0000000000 1 35.500000 36388883.0000000000 | 1 35.500000 622576.0000000000 1 36.000000 36545293.0000000000 | 1 36.000000 682210.0000000000 1 36.500000 36663200.0000000000 | 1 36.500000 628288.0000000000 1 37.000000 36784525.0000000000 | 1 37.000000 615445.0000000000 1 37.500000 36880832.0000000000 | 1 37.500000 612941.0000000000 1 38.000000 36975446.0000000000 | 1 38.000000 588217.0000000000 1 38.500000 37068071.0000000000 | 1 38.500000 618596.0000000000 1 39.000000 37142861.0000000000 | 1 39.000000 553947.0000000000 1 39.500000 37210905.0000000000 | 1 39.500000 578542.0000000000 1 40.000000 37277654.0000000000 | 1 40.000000 576153.0000000000 1 40.500000 37343204.0000000000 | 1 40.500000 531098.0000000000 1 41.000000 37424960.0000000000 | 1 41.000000 587050.0000000000 1 41.500000 37471419.0000000000 | 1 41.500000 505516.0000000000 1 42.000000 37528185.0000000000 | 1 42.000000 555003.0000000000 1 42.500000 37577489.0000000000 | 1 42.500000 526944.0000000000 1 43.000000 37619491.0000000000 | 1 43.000000 517908.0000000000 1 43.500000 37650663.0000000000 | 1 43.500000 521416.0000000000 1 44.000000 37679802.0000000000 | 1 44.000000 470481.0000000000 1 44.500000 37722918.0000000000 | 1 44.500000 540990.0000000000 1 45.000000 37734753.0000000000 | 1 45.000000 478670.0000000000 1 45.500000 9553650.0000000000 | 1 45.500000 483596.0000000000 1 46.000000 9713700.0000000000 | 1 46.000000 485267.0000000000 1 46.500000 9852311.0000000000 | 1 46.500000 477315.0000000000 1 47.000000 9997536.0000000000 | 1 47.000000 472017.0000000000 1 47.500000 10125488.0000000000 | 1 47.500000 457102.0000000000 1 48.000000 10254449.0000000000 | 1 48.000000 443522.0000000000 1 48.500000 10397168.0000000000 | 1 48.500000 471996.0000000000 1 49.000000 10511010.0000000000 | 1 49.000000 446795.0000000000 1 49.500000 10630727.0000000000 | 1 49.500000 445005.0000000000 1 50.000000 10737178.0000000000 | 1 50.000000 420705.0000000000 1 50.500000 11019140.0000000000 | 1 50.500000 441648.0000000000 1 51.000000 10980396.0000000000 | 1 51.000000 432992.0000000000 1 51.500000 11061778.0000000000 | 1 51.500000 398384.0000000000 1 52.000000 11181792.0000000000 | 1 52.000000 417967.0000000000 1 52.500000 11415638.0000000000 | 1 52.500000 409181.0000000000 1 53.000000 11372659.0000000000 | 1 53.000000 414329.0000000000 1 53.500000 11453674.0000000000 | 1 53.500000 401703.0000000000 1 54.000000 11518515.0000000000 | 1 54.000000 371639.0000000000 1 54.500000 11770976.0000000000 | 1 54.500000 387916.0000000000 1 55.000000 11709783.0000000000 | 1 55.000000 398142.0000000000 1 55.500000 11768876.0000000000 | 1 55.500000 372310.0000000000 1 56.000000 11847745.0000000000 | 1 56.000000 375489.0000000000 1 56.500000 12053578.0000000000 | 1 56.500000 359779.0000000000 1 57.000000 11994805.0000000000 | 1 57.000000 382065.0000000000 1 57.500000 12044179.0000000000 | 1 57.500000 362027.0000000000 1 58.000000 12081815.0000000000 | 1 58.000000 335297.0000000000 1 58.500000 12150407.0000000000 | 1 58.500000 351626.0000000000 1 59.000000 12344066.0000000000 | 1 59.000000 339022.0000000000 1 59.500000 12405260.0000000000 | 1 59.500000 351818.0000000000 1 60.000000 12288796.0000000000 | 1 60.000000 325346.0000000000 1 60.500000 12323267.0000000000 | 1 60.500000 314558.0000000000 1 61.000000 12373140.0000000000 | 1 61.000000 326031.0000000000 1 61.500000 12568242.0000000000 | 1 61.500000 343289.0000000000 1 62.000000 12566745.0000000000 | 1 62.000000 301647.0000000000 1 62.500000 12610059.0000000000 | 1 62.500000 315659.0000000000 1 63.000000 12465081.0000000000 | 1 63.000000 285269.0000000000 1 63.500000 12520344.0000000000 | 1 63.500000 318055.0000000000 ``` ### 補足情報(FW/ツールのバージョンなど) 用いたコンパイラは gcc 8.2.0とiccの17.0.1です
回答2件
あなたの回答
tips
プレビュー