我正在尝试使用pthreads进行矩阵乘法, 但不知怎的,我得到了“双重免费或腐败(失败)”错误。
typedef struct {
double *my_x;
double *my_y;
double my_dot_prod;
double *global_dot_prod;
pthread_mutex_t *mutex;
int my_vec_len;
} dot_product_t;
void *serial_dot_product(void *arg) {
dot_product_t *dot_data;
int i;
dot_data = arg;
for(i=0; i<dot_data->my_vec_len; i++)
dot_data->my_dot_prod += dot_data->my_x[i]*dot_data->my_y[i];
pthread_mutex_lock(dot_data->mutex);
*(dot_data->global_dot_prod) += dot_data->my_dot_prod;
pthread_mutex_unlock(dot_data->mutex);
pthread_exit(NULL);
}
int main() {
double *x, *y, dot_prod;
pthread_t *working_thread;
dot_product_t *thrd_dot_prod_data;
void *status;
pthread_mutex_t *mutex_dot_prod;
int num_of_thrds;
int vec_len;
int subvec_len;
double** A;
double** B;
double** C;
int i=0;
int j=0;
int n;
printf ("Enter matrix dimension n: ");
scanf(" %d", &n);
// Matrix A - memory allocation
A =(double **)malloc(n*sizeof(double *));
A[0] = (double *)malloc(n*n*sizeof(double));
A[0] = (double *)malloc(n*n*sizeof(double));
if(!A) {
printf("memory failed \n");
exit(1);
}
for(i=1; i<n; i++) {
A[i] = A[0]+i*n;
if (!A[i]) {
printf("memory failed \n");
exit(1);
}
}
// Matrix B - memory allocation
B =(double **)malloc(n*sizeof(double *));
B[0] = (double *)malloc(n*n*sizeof(double));
if(!B) {
printf("memory failed \n");
exit(1);
}
for(i=1; i<n; i++) {
B[i] = B[0]+i*n;
if (!B[i]){
printf("memory failed \n");
exit(1);
}
}
// Matrix C - memory allocation
C =(double **)malloc(n*sizeof(double *));
C[0] = (double *)malloc(n*n*sizeof(double));
if(!C) {
printf("memory failed \n");
exit(1);
}
for(i=1; i<n; i++) {
C[i] = C[0]+i*n;
if (!C[i]) {
printf("memory failed \n");
exit(1);
}
}
for(i=0; i<n; i++) {
for(j=0; j<n; j++) {
A[i][j] = 1.0;
B[i][j] = 1.0;
C[i][j] = 0.0;
}
}
printf("Number of processors = ");
if(scanf("%d", &num_of_thrds) < 1 || num_of_thrds > MAXTHRDS){
printf("Check input for number of processors. Bye.\n");
return -1;
}
printf("Vector length = ");
if(scanf("%d", &vec_len)<1 || vec_len > n){
printf("Check input for vector length. Bye.\n");
return -1;
}
subvec_len = vec_len/num_of_thrds;
working_thread = malloc(num_of_thrds*sizeof(pthread_t));
thrd_dot_prod_data=malloc(num_of_thrds*sizeof(dot_product_t));
mutex_dot_prod = malloc(sizeof(pthread_mutex_t));
pthread_mutex_init(mutex_dot_prod, NULL);
int k = 0;
int l = 0;
for(j=0;j<n;j++){
for(k=0;k<n;k++){
x = A[j];
y = B[k];
for(i=0; i<num_of_thrds; i++){
thrd_dot_prod_data[i].my_x = x + i*subvec_len;
thrd_dot_prod_data[i].my_y = y + i*subvec_len;
thrd_dot_prod_data[i].global_dot_prod = &dot_prod;
thrd_dot_prod_data[i].mutex = mutex_dot_prod;
thrd_dot_prod_data[i].my_vec_len =
(i==num_of_thrds-1)?vec_len-(num_of_thrds-1)*subvec_len:subvec_len;
pthread_create(&working_thread[i], NULL, serial_dot_product,(void*)&thrd_dot_prod_data[i]);
}
for(i=0; i<num_of_thrds; i++)
pthread_join(working_thread[i], &status);
C[j][k] = dot_prod;
dot_prod = 0.0;
}
}
for(i=0;i<n;i++) {
for(j=0;j<n;j++){
printf("%lf ", C[i][j]);
}
printf("\n");
}
free(A);
free(B[0]);
free(B);
free(C[0]);
free(C);
free(x);
free(y);
free(working_thread);
free(thrd_dot_prod_data);
pthread_mutex_destroy(mutex_dot_prod);
free(mutex_dot_prod);
}
serial_dot_product函数是我用于每个B矩阵的A矩阵和列上的每一行的函数,然后将得到的返回值分配给C [j] [k]。但是,当我运行此操作时,我收到此错误。 Error image
在实际的“双重免费或损坏”错误之前,它给出了一个矩阵,但这是错误的。
答案 0 :(得分:1)
这里有几个问题。
您可以通过分配n
来创建A
元素数组。然后,您创建一个n
元素的二维数组,并将其附加到A
中的第一个元素。两次。 第一次分配丢失,并且是内存泄漏。
对B
和C
执行相同的操作,没有双重分配。
然后,您对A
,B
和C
进行操作,就像它们是二维数组一样,它们不是,所以您要写入“随机”位置内存(即,没有分配内存的地方)正在破坏堆。 您应该将A
,B
和C
分配为二维数组。
完成后,您不会释放A[0]
数组,只释放A
数组。 这会泄漏A [0]分配。在释放B[0]
和C[0]
数组之前,您正确释放了B
和C
数组。 然后你释放x
和y
,它们从未被分配 - 它们只引用已分配的内存。 这是“双重免费”错误的来源。