1

私が書いているACコードに問題があります。指定された次元 (mxn に nxm を掛けた結果が mxm 行列) の 2 つの行列 (0 ~ 9 のランダムな整数で埋められた) を乗算する必要があります。行列は列で埋められます。また、プログラム全体と計算を行う関数の実行の両方の計算時間を出力する必要があります。

アプリケーションの実行中に「glibc が検出されました」というエラーが発生します。私はそれが私のプログラムのヒープの破損によるものであることを知っています。おそらく、エラーがどこにあるかを見つけることができません.

コードは次のとおりです。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define A(i,j) aa[m*(j)+(i)]   //matrix by columns
#define B(i,j) bb[n*(j)+(i)]
#define C(i,j) cc[m*(j)+(i)]

void mmul (int m, int n, double *aa, double *bb, double *cc) {
   int i, j, k;
   for (i=0; i<m; i++)
      for (j=0; j<m; j++) {
         C(i,j)=0;
         for (k=0; k<n; k++)  C(i,j)+=A(i,k)*B(k,j);
      }
}

int main (int argc, char *argv[]) {
   clock_t exec_timer=clock(), comp_timer;
   srand(time(NULL)); //initialize random seed
   int m, n, i;
   double *aa, *bb, *cc, exec_time, comp_time;
   if (argc!=3
       || sscanf(argv[1], "%d", &m)!=1
       || sscanf(argv[2], "%d", &n)!=1
      ) {
      fprintf(stderr, "%s m n \n", argv[0]);
      return -1;
   }
/* malloc memory */
   aa=malloc(m*n*sizeof(int));  //integer matrix
   bb=malloc(n*m*sizeof(int));
   cc=malloc(m*m*sizeof(int));

/* fill matrix */
   for (i=0; i<m*n; i++) aa[i]=rand()%10;   //fill with random integers 0-9
   for (i=0; i<n*m; i++) bb[i]=rand()%10;   
/* compute product */
   comp_timer=clock();
   mmul(m,n,aa,bb,cc);
   comp_time=(double) (clock() - comp_timer) / CLOCKS_PER_SEC;
/* write output */
   for (i=0; i<m*m; i++) printf("%i\n",cc[i]);   
/* finishing */  
   free(aa); free(bb); free(cc);
   exec_time=(double) (clock() - exec_timer) / CLOCKS_PER_SEC;
   printf("exec time = %.3f, comp = %.3f\n", exec_time, comp_time);
   return 0;
}

#undef C
#undef B
#undef A

誰でも私が見逃している問題を見ることができますか?

4

1 に答える 1

4

そうですね、問題はわかります。

の配列をdouble使用していますが、割り当てコードは を使用していますint。通常、 adoubleは an の 2 倍のサイズであるためint、大量のバッファ オーバーフローが発生し、ランダム メモリが破壊されます。

基本的に、これは:

aa=malloc(m*n*sizeof(int));  //integer matrix

嘘をついています。:) そのはず:

aa = malloc(m * n * sizeof *aa);   /* Not an integer matrix! aa is double *. */

もちろん、bbとの割り当てについても同じです。cc

sizeof *aa(「ポインターが指す値のサイズ」を意味する) を使用して、このエラーが発生するリスクを取り除くことに注意しaaてください。つまり、型を手動で繰り返すのではなく、実際のポインターに「ロック」することで、コードをより安全にします。 .

問題とは関係のないマイナーな注意として、次のようconstに への読み取り専用引数を使用する必要がありますmmul()

void mmul (int m, int n, const double *aa, const double *bb, double *cc)

これにより、どのポインターが入力で、どれが出力であるかがすぐにわかります。また、コンパイラがより良いコードを生成するのにも役立ちますが、主な利点は、意図したことをより明確に伝えることです。

于 2013-10-01T08:27:20.803 に答える