简体   繁体   English

矩阵乘法动态分配矩阵错误:分段错误(核心转储)

[英]Matrix multiplication dynamically allocated matrix error: segmentation fault (core dump)

I am writing a matrix multiplication program, and I need to check the running time of different matrices with different sizes. 我正在编写一个矩阵乘法程序,我需要检查不同大小的不同矩阵的运行时间。 Then I need to parallelize my code with pthreads in main, therefore I created one header file, which includes the initialization and multiplication functions, and then my main in a separate .c file, but when I execute my program, I get the following error: 然后我需要在main中将我的代码与pthreads并行化,因此我创建了一个头文件,其中包括初始化和乘法函数,然后我的main在一个单独的.c文件中,但是当我执行我的程序时,我得到以下错误:

error: segmentation fault (core dump) 错误:分段错误(核心转储)

Please note that I'm trying a matrix multiplication of a square matrix with size 1000. 请注意,我正在尝试使用大小为1000的方阵进行矩阵乘法。

Here are my codes: 这是我的代码:

// mm.h

#ifndef MM_H
#define MM_H

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

int SIZE, NTHREADS;
int **A, **B, **C;

void init(int **A, int **B, int **C)
{
    int i, j;

    A = (int**)malloc(SIZE * sizeof(int *));
    for(i = 0; i < SIZE; i++)
        A[i] = malloc(SIZE * sizeof(int));

    B = (int**)malloc(SIZE * sizeof(int *));
    for(i = 0; i < SIZE; i++)
        B[i] = malloc(SIZE * sizeof(int));

    C = (int**)malloc(SIZE * sizeof(int *));
    for(i = 0; i < SIZE; i++)
        C[i] = malloc(SIZE * sizeof(int));

    srand(time(NULL));

    for(i = 0; i < SIZE; i++) {
        for(j = 0; j < SIZE; j++) {
            A[i][j] = rand()%100;
            B[i][j] = rand()%100;
        }
    }
}

void mm(int **A, int **B, int **C)
{
    int i, j, k;

    for(i = 0; i < SIZE; i++) {
        for(j = 0; j < SIZE; j++) {
            C[i][j] = 0;
            for(k = 0; k < SIZE; k++) {
                C[i][j] += A[i][k] * B[k][j];
            }
        }
    }
}

#endif

Any my main function: 我的主要功能:

// mmserial.c

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

int main(int argc, char* argv[])
{
    int i;

    if(argc != 2)
    {
        printf("Usage: %s <size_of_square_matrix>\n", argv[0]);
        exit(1);
    }

    SIZE = atoi(argv[1]);
    init(A, B, C);

    clock_t begin, end;
    double time_spent;

    begin = clock();

    mm(A, B, C);

    end = clock();

    time_spent = (double)(end - begin) / CLOCKS_PER_SEC;

    printf("Elapsed time: %.2lf seconds.\n", time_spent);

    for(i = 0; i < SIZE; i++)
        free((void *)A[i]);
    free((void *)A);

    for(i = 0; i < SIZE; i++)
        free((void *)B[i]);
    free((void *)B);

    return 0;
}

If someone could help me overcome this problem, I would be glad. 如果有人能帮我解决这个问题,我会很高兴的。 And more question, should I also dynamically allocate my final matrix, which will hold the resulting values of the multiplication? 还有更多问题,我是否还应该动态分配我的最终矩阵,它将保存乘法的结果值?

I was looking for final code but no updates available, for those who are interested as well in matrix multiplication by dynamic allocation, here the final code: 我正在寻找最终代码,但没有可用的更新,对于那些对动态分配矩阵乘法感兴趣的人,这里是最终代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void allocate_mem(double*** arr, int rows, int cols);
void deallocate_mem(double*** arr, int n);
void printMatrix(double** a, int rows, int cols);
void printMatrixE(double** a, int rows, int cols);
void multMatrixp(double **A, double **B, double **C,int r1,int c1,int r2,int c2);
void init(double*** a, int rows,int cols);

int main(int argc, char* argv[])
{

   int ro1, co1, ro2, co2;
   double **a, **b, **c;    



//ro1=10;
//co1=10000;
//ro2=10000;
//co2=33;

ro1=atoi(argv[1]);
co1=atoi(argv[2]);
ro2=atoi(argv[3]);
co2=atoi(argv[4]);


init(&a,ro1,co1);
init(&b,ro2,co2);
allocate_mem(&c,ro1,co2);

clock_t begin, end;
double time_spent;
begin = clock();
multMatrixp(a, b, c, ro1, co1, ro2, co2);  
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("Elapsed time: %.2lf seconds.\n", time_spent);

printMatrix(a,ro1,co1); 
printMatrix(b,ro2,co2); 
printMatrixE(c,ro1,co2); 


deallocate_mem(&a,ro1);
deallocate_mem(&b,ro2);
deallocate_mem(&c,ro1);

    return 0;
}

//______________________________________________________________________________
void allocate_mem(double*** arr, int rows, int cols)
{
  int i;
  *arr = (double**)malloc(rows*sizeof(double*));
  for( i=0; i<rows; i++)
    (*arr)[i] = (double*)malloc(cols*sizeof(double));
} 

//______________________________________________________________________________
void deallocate_mem(double*** arr, int rows){
 int i;
    for (i = 0; i < rows; i++)
        free((*arr)[i]);
    free(*arr); 
}

//______________________________________________________________________________

void init(double*** a, int rows,int cols)
{
   int i, j;

*a= (double**) malloc(rows*sizeof(double*));
for(i=0;i<rows;i++)
(*a)[i]=(double*)malloc(cols*sizeof(double));
    for(i=0;i<rows;i++)
        for(j=0;j<cols;j++)
        (*a)[i][j] = rand()%1000;
}


//______________________________________________________________________________
void printMatrix(double** a, int rows, int cols)
{
    int i, j;
   printf("Matrix[%d][%d]\n",rows,cols);    
   for(i=0;i<rows;i++){
      for(j=0;j<cols;j++)
      printf("%7.1lf ",a[i][j]);
      printf("\n");
   }
   printf("\n");   
}

//______________________________________________________________________________
void printMatrixE(double** a, int rows, int cols)
{
    int i, j;
   printf("Matrix[%d][%d]\n",rows,cols);    
   for(i=0;i<rows;i++){
      for(j=0;j<cols;j++)
      printf("%9.2e ",a[i][j]);
      printf("\n");
   } 
   printf("\n");     
}


//______________________________________________________________________________

void multMatrixp(double **A, double **B, double **C,int ro1,int co1,int ro2,int co2)
{
    int i, j, k;
    for(i = 0; i < ro1; i++) {
        for(j = 0; j < co2; j++) {
            C[i][j] = 0;
            for(k = 0; k < co1; k++) {
                C[i][j] += A[i][k] * B[k][j];
            }
        }
    }
}

There are multiple issues with your code. 您的代码存在多个问题。 Here are solutions to your issues in your program. 以下是您的计划中的问题的解决方案。

First , you need to allocate space for C array. 首先 ,您需要为C数组分配空间。 This is already been covered by tacp and hence, I am skipping the same. 这已经被tacp所涵盖,因此,我正在跳过同样的事情

The main issue is coming from init(A,B) function. 主要问题来自init(A,B)函数。 There are couple of issues here. 这里有几个问题。 One, A and B are global pointers and hence, this is really not required to be passed as a function argument. 一, AB是全局指针,因此,实际上不需要将其作为函数参数传递。 However, since your code is designed for the same, you would have to incorporate the following changes 但是,由于您的代码是针对相同的代码设计的,因此您必须包含以下更改

//main function invoking init
init(&A, &B); // Pass references to A and B

The foot print of init needs to be modified as init需要修改为

void init(int ***Aptr, int ***Bptr)
{
     int    **A; // Define a local pointer to keep rest of the code intact
     int    **B; // Define a local pointer to keep rest of the code intact
     .....................
     //Rest of your code

     // End of function
     *Aptr = A;
     *Bptr = B;
}

With these 2 changes, your code should be ready to work fine. 通过这两项更改,您的代码应该可以正常工作了。 In your earlier implementation, only the local copy of A and B were updated in the init function and it wasn't reflected on the actual pointers. 在您之前的实现中,只有AB的本地副本在init函数中更新,并且没有反映在实际指针上。 Hence, when init completed, A and B were pointing to potentially NULL pointers which was the cause of the segmentation fault. 因此,当init完成时, AB指向潜在的NULL指针,这是分段错误的原因。

There is another solution to this problem. 这个问题有另一个解决方案。 You could avoid passing the arguments to init ie convert init to init() and modify the implementation as void init() . 你可以通过避免的参数init ,即转换initinit()和修改的实施为void init() This would work fine (again assuming C is also allocated) 这样可以正常工作(再次假设C也被分配)

However, there is still one more point. 但是,还有一点。 Lastly , you would require to take care to delete the memory for C array also (assuming it is allocated in init function) as 最后 ,您还需要注意删除C数组的内存(假设它在init函数中分配)为

for(i = 0; i < SIZE; i++)
    free((void *)C[i]);
free((void *)C);

Postscript: 后记:

From a programming perspective, I feel you shouldn't mix global variables and passing these very global variables as function parameters. 从编程的角度来看,我觉得你不应该混合全局变量并将这些非常全局的变量作为函数参数传递。 The scope is global which means the function can definitely access the variables and hence, don't require the same to be passed to the function. 范围是全局的,这意味着函数可以绝对访问变量,因此不需要将它传递给函数。

C is also a dynamic matrix, but you never allocated memory for it, directly assign values to nonexist memory, so that's why you have core dump. C也是一个动态矩阵,但你从来没有为它分配内存,直接将值分配给nonxist内存,这就是你有核心转储的原因。 You should also allocate memory for C . 您还应该为C分配内存。

 void mm(int **A, int **B, int **C)
 {
   int i, j, k;

   for(i = 0; i < SIZE; i++) {
      for(j = 0; j < SIZE; j++) {
        C[i][j] = 0;   ///^^^Need to first allocate space for C
        for(k = 0; k < SIZE; k++) {
            C[i][j] += A[i][k] * B[k][j];
        }
      }
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM