【问题标题】:Segmentation Fault while allocating memory at run time using malloc [duplicate]使用 malloc 在运行时分配内存时出现分段错误 [重复]
【发布时间】:2014-07-17 10:08:19
【问题描述】:

这是我的代码。我的目的是在运行时为 2D array 分配内存,直到输入中给出的任何大小。

为什么会出现分段错误?是因为数组元素必须连续存储而ma​​lloc(动态分配)不允许这种情况发生吗? 我在编写此代码时出错。请指导我完成。 提前致谢。

int main(){
    // STEP 1
    int size,**arr,i=0,j=0;
    printf("Enter the size of matrix : ");
    scanf("%d",&size);
    // STEP 2
    arr = (int**)malloc(size*size*sizeof(int));
    printf("\n Enter the %d elements  : \n",size*size);
    for(i=0;i<size;i++){
        for(j=0;j<size;j++){
        // STEP 3
            scanf("%d",&arr[i][j]);
        }
    }
    /*
    for(i=0;i<size;i++){
        for(j=0;j<size;j++){
            printf("%d\n",matrix[i][j]);
        }
    }
    */
    return 0;
}

【问题讨论】:

  • 你用一维数组试过了吗? ?
  • int ** 指的是指向int 的指针,而您似乎正试图将其用作ints 的二维矩阵

标签: c arrays pointers malloc dynamic-memory-allocation


【解决方案1】:

这是一个典型的错误。

指向指针的指针实际上并不等同于二维数组。

当然,您可以通过var[x][y] 语法访问两者的元素,但内存布局的

int foo[x][y]

不同于

int **bar

如果你真的想拥有这种动态,你将不得不为你的指针列表分配空间,然后为你的元素依次分配空间给每个指针。

bar = malloc( x * sizeof(int*) );
for ( int i = 0 ; i < x ; i++ )
    bar[i] = malloc( y * sizeof(int) );

如果可能的话,你应该尽量避免这种情况,而使用实际的二维数组,从 C99 开始,即使它的大小在运行时确定,你也可以在堆栈上声明它:

int main()
{
    int n;
    scanf("%d", &n);
    int array[n][n];
    // ...
    return 0;
}

【讨论】:

  • @MilesRout 是的,如果用户为n 输入了一个较大的值,您可以这样做溢出堆栈。
  • @user3386109 好吧,这是一个关于堆栈溢出的网站,不是吗? - 抱歉无法抗拒。感谢 Miles 关于 C99 的附录。
【解决方案2】:

你应该这样分配:

arr = malloc(size * sizeof(int*));
for (int i = 0; i <size; i++)  
    arr[i] =  malloc(size * sizeof(int));   

不要忘记使用free 释放内存。


旁注:不要转换malloc的返回值。

【讨论】:

  • 不,你不应该。这会导致内存碎片。
  • @MilesRout;那么你将如何创建二维数组?
  • @MilesRout 内存碎片与问题无关。在某些用例中,这是一种很好的方法,而碎片化不是问题。
  • @MilesRout 但不在这个问题中。有很多方法可以在 C 中处理 2D 数组,没有一种比另一种更好。他们只是有不同的权衡。没有理由在不需要时增加答案的复杂性。
  • @MilesRout 我们都知道 OP 想知道为什么他的 malloc 不起作用。我们不知道他最终打算如何使用它,我们不应该做任何假设。对于一个假设的约束,没有必要抨击这个答案,这对 OP 来说甚至可能无关紧要。 VLA 也不是免费的。
【解决方案3】:

一个可行的想法是让你的矩阵线性化:

arr = (int*) malloc (size*size*sizeof(int));

然后只需使用 arr[i*size + j] 而不是 arr[i][j] 访问您的元素:

【讨论】:

    【解决方案4】:

    像这样使用它:动态内存分配的完美示例

    void mxmult()
    {
        int n,m,a,b,c,d, sum=0;
        int x,y,z;
        printf("Enter first order [n*n]\n");
        scanf("%d", &n);
        printf("Enter second order [m*m]\n");
        scanf("%d", &m);
        if (n!=m)
        {
            printf("Invalid orders");
    
        }
        else
        {
            //mem allocate for matrix 1
            int **mat1 = (int**)malloc(n*sizeof(int));
            for(x=0;x<n;x++)
                {
                    mat1[x]=(int*)malloc(n*sizeof(int));
                }
            // input matrix 1
            printf("Enter the first matrix entries\n");
            for (a = 0; a <n; a++)
            {
                for (b = 0; b < n; b++)
                {
                    scanf("%d", &mat1[a][b]);   
                }
            }
            // memory allocate matrix 2
            int **mat2 = (int**)malloc(m*sizeof(int));
            for(y=0;y<n;y++)
                {
                    mat2[y]=(int*)malloc(m*sizeof(int));
                }
    
            //inpur matrix 2
            printf("Enter the second matrix entries\n");
            for (c = 0; c <n; c++)
            {
                for (d= 0; d < n; d++)
                {
                    scanf("%d", &mat2[c][d]);   
                }
            }
    
            //Memory allocate matrix Mult
            int **mult=(int**)malloc(m*sizeof(int));
            for(z=0;z<m;z++)
                mult[z]=(int*)malloc(m*sizeof(int));
            for (a = 0; a < n; a++)
            {
                for (d = 0; d < m; d++)
                {
                    for (c = 0; c < n; c++)
                    {
                        sum=sum + (mat1[a][c] *mat2[c][d]);
                    }
                    mult[a][d] = sum;
                    sum= 0;
                }
            }
            printf("Product\n");
    
            for ( a = 0 ; a < n ; a++ )
            {
                for ( d = 0 ; d < m ; d++)
                    printf("%d\t", mult[a][d]);
                printf("\n");
            }
    
        }
    }  
    

    【讨论】:

      猜你喜欢
      • 2018-05-15
      • 2018-06-06
      • 2017-06-06
      • 1970-01-01
      • 1970-01-01
      • 2018-09-24
      • 1970-01-01
      • 2015-12-26
      相关资源
      最近更新 更多