C 矩阵乘法动态分配矩阵错误:分段错误(堆芯转储)

C 矩阵乘法动态分配矩阵错误:分段错误(堆芯转储),c,memory,time,matrix,dynamic-allocation,C,Memory,Time,Matrix,Dynamic Allocation,我正在写一个矩阵乘法程序,我需要检查不同大小的不同矩阵的运行时间。然后我需要在main中使用pthreads并行我的代码,因此我创建了一个头文件,其中包括初始化和乘法函数,然后在一个单独的.c文件中并行我的main,但是当我执行程序时,我得到以下错误: 错误:分段错误(堆芯转储) 请注意,我正在尝试一个大小为1000的方阵的矩阵乘法 这是我的密码: // mm.h #ifndef MM_H #define MM_H #include <stdlib.h> #include <

我正在写一个矩阵乘法程序,我需要检查不同大小的不同矩阵的运行时间。然后我需要在main中使用pthreads并行我的代码,因此我创建了一个头文件,其中包括初始化和乘法函数,然后在一个单独的.c文件中并行我的main,但是当我执行程序时,我得到以下错误:

错误:分段错误(堆芯转储)

请注意,我正在尝试一个大小为1000的方阵的矩阵乘法

这是我的密码:

// 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
//mm.h
#ifndef MM_H
#定义MM_H
#包括
#包括
int大小,n个字符;
内部**A、**B、**C;
无效初始值(整数**A、整数**B、整数**C)
{
int i,j;
A=(int**)malloc(SIZE*sizeof(int*);
对于(i=0;i
我的主要职能是:

// 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;
}
//mmserial.c
#包括
#包括
#包括
#包括“mm.h”
int main(int argc,char*argv[])
{
int i;
如果(argc!=2)
{
printf(“用法:%s\n”,argv[0]);
出口(1);
}
大小=atoi(argv[1]);
初始(A,B,C);
时钟开始,结束;
花费的时间加倍;
开始=时钟();
mm(A,B,C);
结束=时钟();
花费的时间=(双倍)(结束-开始)/每秒时钟;
printf(“已用时间:%.2lf秒。\n”,所用时间);
对于(i=0;i

如果有人能帮我克服这个问题,我会很高兴。还有一个问题,我是否也应该动态分配我的最终矩阵,它将保存乘法的结果值?

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];
        }
      }
   }
}
void mm(int**A,int**B,int**C)
{
int i,j,k;
对于(i=0;i
您的代码存在多个问题。以下是您计划中问题的解决方案

首先,您需要为
C
数组分配空间。这已经被tacp涵盖,因此,我跳过了相同的部分

主要问题来自
init(A,B)
函数。这里有几个问题。第一,
A
B
是全局指针,因此,实际上不需要将其作为函数参数传递。但是,由于您的代码是为同样的目的而设计的,因此您必须合并以下更改

//main function invoking init
init(&A, &B); // Pass references to A and B
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;
}
有了这两个更改,您的代码就可以正常工作了。在早期的实现中,在
init
函数中只更新了
A
B
的本地副本,而没有反映在实际指针上。因此,当
init
完成时,
A
B
指向可能导致分段错误的
NULL
指针

这个问题还有另一个解决方案。您可以避免将参数传递给
init
,即将
init
转换为
init()
,并将实现修改为
void init()
。这将很好地工作(再次假设还分配了
C

然而,还有一点最后,您还需要注意删除
C
数组的内存(假设它在
init
函数中分配)

for(i=0;i
附言:


从编程的角度来看,我觉得不应该混合使用全局变量并将这些全局变量作为函数参数传递。作用域是全局的,这意味着函数可以明确地访问变量,因此不需要将变量传递给函数。

我正在寻找最终代码,但没有可用的更新,对于那些对通过动态分配进行矩阵乘法感兴趣的人来说,最终代码如下:

#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];
            }
        }
    }
}
#包括
#包括
#包括
void allocate_mem(双***arr、整数行、整数列);
无效解除分配成员(双倍***arr,整数n);
无效打印矩阵(双**a,整数行,整数列);
无效打印矩阵(双**a,整数行,整数列);
无效多矩阵XP(双**A、双**B、双**C、整数r1、整数c1、整数r2、整数c2);
void init(双***a,整数行,整数列);
int main(int argc,char*argv[])
{
int ro1、co1、ro2、co2;
双**a、**b、**c;
//ro1=10;
//co1=10000;
//ro2=10000;
//二氧化碳=33;
ro1=atoi(argv[1]);
co1=atoi(argv[2]);
ro2=atoi(argv[3]);
co2=atoi(argv[4]);
初始(&a、ro1、co1);
初始浓度(&b、ro2、co2);
分配_mem(&c、ro1、co2);
时钟开始,结束;
花费的时间加倍;
开始=时钟();
multMatrixp(a、b、c、ro1、co1、ro2、co2);
结束=时钟();
花费的时间=(双倍)(结束-开始)
#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];
            }
        }
    }
}