简体   繁体   English

二维数组动态分配中的分割错误

[英]segmentation fault in dynamic allocation of a 2D array

this code worked fine for n=10,000 but for n=100,000 on a machine with 2GB ram. 此代码在n = 10,000的情况下可以正常工作,但在具有2GB内存的计算机上可以达到n = 100,000。 kswap0 was called for n=10,000 on a machine with 1GB ram but immediately showed segmentation fault for n=100,000. 在内存为1GB的计算机上,调用kswap0的n = 10,000,但立即显示n = 100,000的分段错误。

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int **createMatrix(int n)
{
    int **mat=(int**)malloc(n*sizeof(int*));
    int i;
    for(i=0;i<n;i++)
    {
        mat[i]=(int*)malloc(n*sizeof(int));
    }
    return mat;
}
void display(int **mat, int n)
{
    int i,j;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            printf("%d\t",mat[i][j]);
        }
        printf("\n");
    }
}
int main()
{
    int n=100000;
    int **matrixOne=createMatrix(n);
    int **matrixTwo=createMatrix(n);
    int **resultantMatrix=createMatrix(n);
    srand(time(NULL));
    int i,j;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            matrixOne[i][j]=rand()%10;
            matrixTwo[i][j]=rand()%10;
        }
    }
    display(matrixOne,n);
    display(matrixTwo,n);
    int k;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            for(k=0;k<n;k++)
            {
                resultantMatrix[i][j]+=matrixOne[i][k]*matrixTwo[k][j];
            }
        }
    }
    display(resultantMatrix,n);
    for(i=0;i<n;i++)
    {
        free(matrixOne[i]);
        free(matrixTwo[i]);
        free(resultantMatrix[i]);
    }

Thank you in advance! 先感谢您!

An int is 4 bytes. 一个int是4个字节。 In createMatrix, ignoring the first malloc, you're allocating n * n * sizeof(int) bytes. 在createMatrix中,忽略第一个malloc,您将分配n * n * sizeof(int)个字节。 For n=100,000, this is 40,000,000,000 bytes, or about 40 GB. 对于n = 100,000,这是40,000,000,000字节,约40 GB。 Since you're doing this 3 times, you'd need about 120 GB of RAM, which you don't have. 由于您已经执行了3次,因此需要大约120 GB的RAM,而您没有。 For n = 10,000, you only need about 1.2 GB, which you do have (including swap space). 对于n = 10,000,您仅需要约1.2 GB(包括交换空间)。

As the comments mentioned, you should check the result of malloc to get a clearer error message, and avoid the seg fault. 如前所述,您应该检查malloc的结果以获得更清晰的错误消息,并避免seg错误。

I can not allocate memory, because matrix is too big for my RAM. 我无法分配内存,因为矩阵对于我的RAM来说太大了。 Check result of malloc every time 每次检查malloc的结果

int **createMatrix(int n) {
    int **mat = NULL;
    int i;

    mat = malloc(n*sizeof(int*));
    if (mat == NULL) {
        exit(1);
    }
    for (i = 0; i<n; i++) {
        mat[i] = malloc(n*sizeof(int));
        if (mat[i] == NULL) {
            exit(2);
        }
    }
    return mat;
}

This approach is not optimal for memory use because you use more RAM than necessary. 这种方法对于内存使用不是最佳的,因为您使用了不必要的RAM。 You create a matrix as an array of array, so for each row you allocate you have a memory overhead: 您将矩阵创建为数组数组,因此,为您分配的每一行都有内存开销:

  • The first 1D array you allocate don't contains data but pointers. 您分配的第一个1D数组不包含数据,而是包含指针。
  • The C runtime library will creates heap meta-data C运行时库将创建堆元数据

While this is kind of nice because you can write M[i][j] like a static 2D array, you will also have much slower allocation (and deallcoation) than a traditional 1D array with row-major or column-major indexing: 虽然这很不错,因为您可以像静态2D数组一样编写M [i] [j],但与具有行主索引或列主索引的传统1D数组相比,分配(和取消分配)的速度也要慢得多:

//allocation:
int * M = malloc(nCol * nRow * sizeof(int));

//access:
M[i + nRow*j] = data; // Column major
M[i*nCol + j] = data; // Row major

//deallocation:
free(M);

http://en.wikipedia.org/wiki/Row-major_order http://en.wikipedia.org/wiki/Row-major_order

Finally, data access implies a double dereference that is likely to be slower that row-major or column-major indexing. 最后,数据访问意味着双重取消引用,这可能比主要行索引或主要列索引的速度慢。

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

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