0

I am a newbie to C programming (relearning it after a long time) . I am trying to dynamically allocate memory to a 2D array using malloc. I have tried following the answers on stackoverflow like this and this. But I still get the segmentation fault.

My code is as below

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

void allocate2DArray(int **subset, int a, int b)
{
  subset = (int **)malloc( a * sizeof(int *));
  int i,j;

  for(i = 0 ; i < a ; i++)
    subset[i] = (int *) malloc( b * sizeof(int));

  for(i = 0 ; i < a ; i++)
     for(j = 0 ; j < b ; j++)
        subset[i][j] = 0;
}

int main()
{
  int **subset;
  int  a = 4, b = 4;
  allocate2DArray(subset, a, b);
  int i,j;
  for( i = 0 ; i < a  ; i++)
  { 
     for( j = 0 ; j < b ; j++)
     {
        printf("%d ", subset[i][j]);
     }
     printf("\n");
  }
} 

When I comment the lines to print the array, it doens't give any error and program executes without segmentation fault. Please help me understand where I am going wrong.

Community
  • 1
  • 1
quirkystack
  • 1,387
  • 2
  • 17
  • 42
  • Function arguments in C are passed *by value*. So your function call in `main` does nothing (except for leaking memory). – Kerrek SB Jun 27 '13 at 23:46

4 Answers4

2

All problems in computer science can be solved by another level of indirection:

void allocate2DArray(int ***p, int a, int b)
{
    int **subset;
    *p = (int **) malloc(a * sizeof(int *));
    subset = *p;

// ...
allocate2DArray(&subset, a, b);
ctn
  • 2,887
  • 13
  • 23
  • 1
    Thanks @ctn ..that worked. I also tried it without using the int **subset. like this.. `*p = (int **)malloc(a * sizeof(int *)); for( i = 0 ; i < a ; i++) { (*p)[i] = (int *)malloc(b * sizeof(int)); } for(i = 0 ; i < a ; i++) for(j = 0 ; j < b ; j++) (*p)[i][j] = i+j; }` Couldn't get why this is not working. Any idea why? – quirkystack Jun 28 '13 at 00:44
  • @quirkystack For me `void allocate2DArray(int ***p, int a, int b) { int i, j; *p = (int**)malloc(a*sizeof(int *)); for(i=0; i – ctn Jun 28 '13 at 09:24
  • my mistake.. didn't add paranthesis around *p in my actual program. Thanks – quirkystack Jun 28 '13 at 22:49
0

you must pass a int ***subset to the allocation function. This because arguments are passed by value.

Emanuele Paolini
  • 9,912
  • 3
  • 38
  • 64
0

You need this:

void allocate2DArray(int ***subset, int a, int b)

and this:

allocate2DArray(&subset, a, b);
jh314
  • 27,144
  • 16
  • 62
  • 82
  • This doesn't work. While compiling it gives two warnings: (1) `assignment to ‘int ***’ from incompatible pointer type ‘int **’` (2) `assignment to ‘int **’ from incompatible pointer type ‘int *’`. And gives segmentation fault when executing. – Abdo Feb 17 '21 at 11:43
0

By using int **subset; it does not become 2D array. It is still 1D storage and just pointer to pointer.

2D array means each element of a pointer buffer must point to a buffer which is suggested by ctn. He has suggested ***ptr and *ptr is malloced which created 1st dimension of buffer. Now when you call allocate2DArray() again subset is allocated memory which create second dimension. Which validate my above statement - each element of pointer buffer must point to a buffer.

so now with suggested code -

 *p = (int **) malloc(a * sizeof(int *));

created an array each element of which point to buffer 'subset' which altogether create a true 2D array.

Vicky
  • 168
  • 7