簡體   English   中英

矩陣乘法動態分配矩陣錯誤:分段錯誤(核心轉儲)

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

我正在編寫一個矩陣乘法程序,我需要檢查不同大小的不同矩陣的運行時間。 然后我需要在main中將我的代碼與pthreads並行化,因此我創建了一個頭文件,其中包括初始化和乘法函數,然后我的main在一個單獨的.c文件中,但是當我執行我的程序時,我得到以下錯誤:

錯誤:分段錯誤(核心轉儲)

請注意,我正在嘗試使用大小為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

我的主要功能:

// 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;
}

如果有人能幫我解決這個問題,我會很高興的。 還有更多問題,我是否還應該動態分配我的最終矩陣,它將保存乘法的結果值?

我正在尋找最終代碼,但沒有可用的更新,對於那些對動態分配矩陣乘法感興趣的人,這里是最終代碼:

#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];
            }
        }
    }
}

您的代碼存在多個問題。 以下是您的計划中的問題的解決方案。

首先 ,您需要為C數組分配空間。 這已經被tacp所涵蓋,因此,我正在跳過同樣的事情

主要問題來自init(A,B)函數。 這里有幾個問題。 一, AB是全局指針,因此,實際上不需要將其作為函數參數傳遞。 但是,由於您的代碼是針對相同的代碼設計的,因此您必須包含以下更改

//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;
}

通過這兩項更改,您的代碼應該可以正常工作了。 在您之前的實現中,只有AB的本地副本在init函數中更新,並且沒有反映在實際指針上。 因此,當init完成時, AB指向潛在的NULL指針,這是分段錯誤的原因。

這個問題有另一個解決方案。 你可以通過避免的參數init ,即轉換initinit()和修改的實施為void init() 這樣可以正常工作(再次假設C也被分配)

但是,還有一點。 最后 ,您還需要注意刪除C數組的內存(假設它在init函數中分配)為

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

后記:

從編程的角度來看,我覺得你不應該混合全局變量並將這些非常全局的變量作為函數參數傳遞。 范圍是全局的,這意味着函數可以絕對訪問變量,因此不需要將它傳遞給函數。

C也是一個動態矩陣,但你從來沒有為它分配內存,直接將值分配給nonxist內存,這就是你有核心轉儲的原因。 您還應該為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