2013-10-01 89 views
1

我遇到了一个我正在编写的c代码的问题。它必须乘以一个给定维数(m×n乘以n×m,结果是一个m×m矩阵)的2矩阵(用0到9之间的随机整数填充)。矩阵由列填充。另外,我必须输出整个程序和执行计算功能的计算时间。“glibc detected”c代码错误

我在执行应用程序时遇到“glibc detected”错误。我知道这是由于我的程序中存在堆损坏,很可能是由于在malloc'ed数组上写了外部内存,我无法找到错误所在。

下面是代码:

#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 

任何人都可以看到,我错过了什么问题?

+0

请指定完整的错误信息,例如* free():下一个尺寸无效(快):0x097a9008 *。 – Oswald

回答

4

嗯,是的,我可以看到问题。

您正在使用double的数组,但您的分配代码使用int。由于通常doubleint大小的两倍,因此会导致可怕的缓冲区溢出,导致随机内存丢失。

基本上,这个:

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

是在撒谎。 :)它应该是:

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

与同为中bbcc,当然分配。

注意使用sizeof *aa(意思是“指针aa指向的值的大小”)来消除引入此错误的风险,即不要手动重复类型,而是将其“锁定”为实际指针,你会让代码更安全。

作为未成年人注意,不是相关的问题,您应该使用const为只读参数mmul(),像这样:

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

这立即使得它显然它的指针(S)是输入,并输出。它还可以帮助编译器生成更好的代码,但主要优点是它可以更清楚地传达您的意思。

+0

谢谢。我只是重复使用旧代码的那部分代码,却没有注意到它们被定义为double,并且在重新读取时无法找到它。 – gunbl4d3