使用C语言乘以随机生成的大尺寸矩阵时出错

使用C语言乘以随机生成的大尺寸矩阵时出错,c,matrix,optimization,matrix-multiplication,C,Matrix,Optimization,Matrix Multiplication,我的主要目的是通过在不同的环境中对C和Java中的矩阵乘法算法进行基准测试,来演示虚拟化与容器化的区别,并得出合适的结论 我选择此算法的原因是,矩阵乘法是各种计算机科学领域中非常常用的算法,因为大多数算法处理的是大尺寸,我希望优化我的代码,使其能够执行至少2000x2000个矩阵大小的操作,以便两者之间的差异显而易见 我在Linux上使用GCC,在Windows上使用Code::Blocks中的默认编译器(我不知道使用的是哪个版本的GCC) 问题是,当我在Windows上运行代码时,编译器只接受

我的主要目的是通过在不同的环境中对C和Java中的矩阵乘法算法进行基准测试,来演示虚拟化与容器化的区别,并得出合适的结论

我选择此算法的原因是,矩阵乘法是各种计算机科学领域中非常常用的算法,因为大多数算法处理的是大尺寸,我希望优化我的代码,使其能够执行至少2000x2000个矩阵大小的操作,以便两者之间的差异显而易见

我在Linux上使用GCC,在Windows上使用Code::Blocks中的默认编译器(我不知道使用的是哪个版本的GCC)

问题是,当我在Windows上运行代码时,编译器只接受高达490x490的大小,如果超过该大小,则转储内核。Linux成功地克服了这一点,但不能超过590x590

我最初认为是我的设备内存造成的,于是让我的几个拥有更好机器的朋友运行相同的代码,但结果还是一样的

仅供参考:我运行的是奔腾N3540和4GB的DDR3内存。我的朋友使用16GB DDR4运行i7-8750H,另一个使用8GB DDR4运行i5-9300H

以下是我编写的代码:

#include <stdio.h>
#include <stdlib.h>
#define MAX 10

int main()
{
    long i, j, k, m, n;
    printf("Enter the row dimension of the matrix: "); scanf("%ld", &m);
    printf("Enter the column dimension of the matrix: "); scanf("%ld", &n);
    long mat1[m][n], mat2[m][n], mat3[m][n];

    for(i=0; i<m; i++)
        for(j=0; j<n; j++)
        {
            mat1[i][j] = (long)rand()%MAX;
            mat2[i][j] = (long)rand()%MAX;
            mat3[i][j] = 0;
        }

    printf("\n\nThe matrix 1 is: \n");
    for(i=0; i<m; i++)
    {
        for(j=0; j<n; j++)
        {
            printf("%d\t", (int)mat1[i][j]);
        }
        printf("\n");
    }

    printf("\n\nThe matrix 2 is: \n");
    for(i=0; i<m; i++)
    {
        for(j=0; j<n; j++)
        {
            printf("%d\t", (int)mat2[i][j]);
        }
        printf("\n");
    }

    for (i = 0; i < m; i++)
        for (j = 0; j < n; j++)
            for (k = 0; k < n; k++)
                mat3[i][j] += mat1[i][k] * mat2[k][j];

    printf("\n\nThe resultant matrix is: \n");
    for(i=0; i<m; i++)
    {
        for(j=0; j<n; j++)
        {
            printf("%d\t", (int)mat3[i][j]);
        }
        printf("\n");
    }
    return 0;
}
#包括
#包括
#定义最大值10
int main()
{
长i,j,k,m,n;
printf(“输入矩阵的行维度:”;scanf(“%ld”,&m);
printf(“输入矩阵的列维度:”;scanf(“%ld”,&n);
长mat1[m][n]、mat2[m][n]、mat3[m][n];
对于(i=0;i除了’s建议使用
malloc()
,您还可以简单地使用
static
将变量设置为全局变量,强制将其放置在堆的堆栈之外——假设您不介意不可变的矩阵

因为无论如何,您必须创建可变长度的数组,
malloc()
自然适合您的用例

堆栈用于小东西;堆用于大东西——用你自己的话来说,这些是“大尺寸”的矩阵:

对于那些在C编程方面更有经验的人来说,作为旁注-为什么不更多的C教科书讲授堆栈理论和非
malloc()变量的大小限制?
ed
auto
variables?
为什么每个新手都必须趴在地上学习,并在S.O上被告知这一点?

当你这样做的时候

long mat1[m][n], mat2[m][n], mat3[m][n];
您创建了一个具有自动存储持续时间的对象(也称为变量)。这意味着一旦函数执行,该对象将自动创建,并在函数退出时自动销毁

C标准没有描述如何做到这一点。这由实现该标准的系统决定。最常见的方法是使用所谓的堆栈。它是为程序预先分配的内存区域。每当程序调用函数时,函数中定义的任何变量都可以放在该堆栈上。这允许或者非常简单和快速地为这些变量分配内存

但是,它有一个缺点-堆栈的大小有限(而且相当小)。因此,如果函数使用了大量变量,则可能会耗尽堆栈内存。不幸的是,大多数系统直到为时已晚才检测到这一点

避免这种情况的简单规则是:不要定义具有自动存储持续时间的大型变量(也称为大型函数局部变量)

因此,对于您的具体示例,您应该替换:

long mat1[m][n]


使用堆而不是堆栈。有关问题的解释,请参阅本网站的名称:-)将
m
乘以
n
以获得
mat1
mat2
mat3
中每一个所需的元素数。乘以
3
以获得所有三个矩阵的元素总数ces.乘以
sizeof(long)
(4或8)以获得所有数组所需的字节大小。将该大小与系统上堆栈的标准大小(Linux上为8 MiB,Windows上为1 MiB)进行比较。这将有助于您了解问题所在。使用
printf(“%d\t”,(int)mat3[i][j]);
(“%ld\t”,mat3[i][j]);
应该
mat1[i][j]
的值为0到
MAX
或0到
MAX-1
?非常感谢您指定这一点!我从未考虑过使用动态内存分配的可能性(尽管我觉得我不应该错过这一点)。
long (*mat1)[n] = malloc(m * sizeof *mat1); // This defines mat1 as a pointer
if (mat1 == NULL)                           // to an array of n longs and
{                                           // allocate memory of m such arrays.
    // Out of memory                        // In other words:
    exit(1);                                // A m by n matrix of long
}

// From here on you can use mat1 as a 2D matrix
// example:
mat1[4][9] = 42;

...

// Once you are done using mat1, you need to free the memory. Like:
free(mat1);