c - 尝试将两个尺寸为 1000*1000 的大矩阵相乘会导致段错误

标签 c linux matrix

<分区>

尝试将维度为 1000*1000 的两个矩阵相乘。但是,尝试这样做会导致 Segmentation fault。可能是什么原因造成的,如何解决?

#include <stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
clock_t t;
    t = clock();
   long int a[1000][1000], b[1000][1000], result[1000][1000], r1=1000, c1=1000, r2=1000, c2=1000, i, j, k;

   // Column of first matrix should be equal to column of second matrix and
  /*  while (c1 != r2)
    {
        printf("Error! column of first matrix not equal to row of second.\n\n");
        printf("Enter rows and column for first matrix: ");
        scanf("%d %d", &r1, &c1);
        printf("Enter rows and column for second matrix: ");
        scanf("%d %d",&r2, &c2);
    }
*/

    // Storing elements of first matrix.
    printf("\nEnter elements of matrix 1:\n");
    for(i=0; i<r1; ++i)
        for(j=0; j<c1; ++j)
        {
          a[i][j]=rand()%20;
        }

    // Storing elements of second matrix.
    printf("\nEnter elements of matrix 2:\n");
    for(i=0; i<r2; ++i)
        for(j=0; j<c2; ++j)
        {
            b[i][j]=rand()%20;
        }

    // Initializing all elements of result matrix to 0
    for(i=0; i<r1; ++i)
        for(j=0; j<c2; ++j)
        {
            result[i][j] = 0;
        }

    // Multiplying matrices a and b and
    // storing result in result matrix
    for(i=0; i<r1; ++i)
        for(j=0; j<c2; ++j)
            for(k=0; k<c1; ++k)
            {
                result[i][j]+=a[i][k]*b[k][j];
            }
 // Displaying the result
    printf("\nOutput Matrix:\n");
    for(i=0; i<r1; ++i)
        for(j=0; j<c2; ++j)
        {
            printf("%ld  ", result[i][j]);
            if(j == c2-1)
                printf("\n\n");
        }
t = clock() - t;
    double time_taken = ((double)t)/CLOCKS_PER_SEC; // in seconds

    printf("\n \nfunction took %f seconds to execute \n", time_taken);
    return 0;
}

最佳答案

在大内存分配的情况下,您需要使用动态内存分配。堆栈内存无法处理这些大内存需求。

您可以使用动态内存分配来解决这个问题。尝试:-

int (*a)[r1][c1] = malloc(sizeof *a);
int (*b)[r2][c2] = malloc(sizeof *b);
int (*result)[r1][c2] = malloc(sizeof *result);

并使用以下方式访问元素:-

(*result)[i][j] ;
(*a)[i][k] ;
(*b)[k][j] ;

试试这段代码:-

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
    clock_t t;
    t = clock();
    int r1 = 1000, c1 = 1000, r2 = 1000, c2 = 1000, i, j, k;

    // Dynamic allocation.

    int(*a)[r1][c1] = malloc(sizeof *a);
    int(*b)[r2][c2] = malloc(sizeof *b);
    int(*result)[r1][c2] = malloc(sizeof *result);

    // Storing elements of first matrix.
    printf("\nEnter elements of matrix 1:\n");
    for (i = 0; i < r1; ++i)
    {
        for (j = 0; j < c1; ++j)
        {
            (*a)[i][j] = rand() % 20;
        }
    }

    // Storing elements of second matrix.
    printf("\nEnter elements of matrix 2:\n");

    for (i = 0; i < r2; ++i)
    {
        for (j = 0; j < c2; ++j)
        {
            (*b)[i][j] = rand() % 20;
        }
    }
    // Initializing all elements of result matrix to 0
    for (i = 0; i < r1; ++i)
    {
        for (j = 0; j < c2; ++j)
        {
            (*result)[i][j] = 0;
        }
    }
    // Multiplying matrices a and b and
    // storing result in result matrix
    for (i = 0; i < r1; ++i)
        for (j = 0; j < c2; ++j)
            for (k = 0; k < c1; ++k)
            {
                (*result)[i][j] += (*a)[i][k] * (*b)[k][j];
            }
    // Displaying the result
    printf("\nOutput Matrix:\n");
    for (i = 0; i < r1; ++i)
        for (j = 0; j < c2; ++j)
        {
            printf("%d  ", (*result)[i][j]);
            if (j == c2 - 1)
                printf("\n\n");
        }
    t = clock() - t;
    double time_taken = ((double)t) / CLOCKS_PER_SEC; // in seconds

    printf("\n \nfunction took %f seconds to execute \n", time_taken);

    free(a);
    free(b);
    free(result);
    return 0;
}

输出:-

.......................................................................
 91717  92211  96529  90328  89167  88774  90433  88320  93834  89054  92225  92226  89919  88005  90772  90436  89091  92446  88477  94143  95777  88805  88487  89082  92528  88899  93436  90423  88637  90254  91569  87516  89079  91309  93554  86422  90069  91096  86981  95437  92805  88638  89828  88568  89607  88025  91700  88144  90401  91147  88284  92998  90959  85520  92640  92247  95616  90006  87248  89726  91751  90077  90543  91489  92399  90828  89026  92866  91548  87131  88450  93247  87748  90734  90228  91972  93300  92444  91592  85842  91167  89554  91144  90536  91256  89646  92815  91476  91863  94836  95462  87122  91735  96059  91312  90480  93306  



function took 6.060788 seconds to execute 

注意:由于太大,无法包含完整输出。

不要忘记释放分配的内存。

关于c - 尝试将两个尺寸为 1000*1000 的大矩阵相乘会导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51705514/

相关文章:

c++ - 标量代码和并行代码之间的不同行为

c - 可视化原始图像数据

r - 如何将r中的矩阵中的十六进制转换为二进制?

c - 在解析树中打印第三个字符串时出现段错误

c - 使用指针变量 typedef

c++ - 如何恢复linux当前所有进程

c++ - ARM 中的图像处理(埃)

linux - 在 linux 中通过代理代理

file - 强制 dlmread 返回 uint8 矩阵 - 可能吗?

python - 如何将列向量组合成矩阵