1

This is my code. My purpose is to allocate memory to a 2D array at run time upto whatever size is given in input.

Why is segmentation fault occuring? Is it because array elements have to be stored consecutively and malloc(dynamic allocation) is not letting this happen? OR I am doing some error in writing this code. Please guide me through. Thanks in advance.

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;
}
Ekansh Gupta
  • 417
  • 1
  • 5
  • 14

4 Answers4

3

This is a classic mistake.

A pointer to pointers is actually not the same as a two-dimensional array.

Granted, you can access elements of both via the var[x][y] syntax, but the memory layout of

int foo[x][y]

is different from

int **bar

If you really want to have this dynamic, you will have to allocate space for your list of pointers, then allocate space for your elements to each pointer in turn.

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

If at all possible, you should try and avoid this in favor of an actual two-dimensional array, which as of C99 you can declare on the stack even if its size is determined at runtime:

int main()
{
    int n;
    scanf("%d", &n);
    int array[n][n];
    // ...
    return 0;
}
Miles Rout
  • 1,204
  • 1
  • 13
  • 26
Felix Frank
  • 8,125
  • 1
  • 23
  • 30
  • @MilesRout Yes, and you can overflow the stack doing that, if the user enters a large value for `n`. – user3386109 May 28 '14 at 09:29
  • @user3386109 well, this is a site about stack overflows, no? - Sorry couldn't resist. Thanks to Miles for the addendum regarding C99. – Felix Frank May 28 '14 at 09:31
2

You should allocate like this:

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

And do not forget to free the memeory using free.


Side Note: Do not cast the return value of malloc.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
  • No you shouldn't. That will result in memory fragmentation. – Miles Rout May 28 '14 at 09:14
  • @MilesRout; Then how would you create 2D array ? – haccks May 28 '14 at 09:22
  • 3
    @MilesRout Memory fragmentation is irrelevant to the question. There are use-cases where this is a good approach and fragmentation is a non-issue. – user694733 May 28 '14 at 09:23
  • @user694733 memory fragmentation is a very relevant performance issue. – Miles Rout May 28 '14 at 10:01
  • 1
    @MilesRout But not in this question. There are many ways to do 2D arrays in C, and none is better than the other. They simply have different trade-offs. There is no reason add complexity to answers when it is not needed. – user694733 May 28 '14 at 10:11
  • Agreed with @user694733. – haccks May 28 '14 at 10:13
  • @user694733 allocating it in one block is much better than allocating a 'ragged' array if you don't want a ragged array. It reduces the level of indirection (which is confusing to beginners especially, not to mention inefficient). It reduces memory fragmentation. It reduces memory usage. If you want an array of strings obviously allocate 'ragged-style'. If you want an NxN matrix then don't. OP wants a matrix. – Miles Rout May 28 '14 at 11:12
  • 1
    @MilesRout All we know that OP wanted to know why his **malloc** didn't work. We don't know how he intends to use it in the end, and we shouldn't make assumptions. There is no need to bash this answer for one assumed constraint, which may not even matter to OP. VLA's are not a free ride either. – user694733 May 28 '14 at 11:28
1

One idea that would work and would also get you rid of the memory fragmentation induced by this double pointers level allocation is make your matrix linear:

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

And then simply access your elements with arr[i*size + j] instead of arr[i][j]:

dragosht
  • 3,237
  • 2
  • 23
  • 32
0

use it like this : a perfect example of dynamic memory Allocation

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");
        }

    }
}  
vaibhav
  • 396
  • 2
  • 17