-2

I don't know where I'm wrong and I get segmentation fault error. Can you help?

My Code;

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

void do_array(int x, int y, int **arr){
    arr=(int **)malloc(sizeof(int)*x);
    for (int i=0;i<y;i++){
        *(arr+i)=(int *)malloc(sizeof(int)*y);
    }
}

int main(){
    int **p;
    do_array(5,2,p);
    for (int i=0;i<5;i++){
        for (int j=0;j<2;j++){
            *(*(p+i)+j)=i;
        }
    }
    for (int i=0;i<5;i++){
        for (int j=0;j<2;j++){
            printf("%d\n",*(*(p+i)+j));
        }
    }
    return 0;
}

!!! I want to do is create a dynamic 2D array

ege ramza
  • 1
  • 1

3 Answers3

0
int main(){
    int **p /* = NULL */ ;         // p is garbage       or NULL
    do_array(5,2,p);               // p is still garbage or NULL
    for (int i=0;i<5;i++){
        for (int j=0;j<2;j++){
            *(*(p+i)+j)=i;         // p is still garbage or NULL
pmg
  • 106,608
  • 13
  • 126
  • 198
0

The formal argument arr in the function is a separate object from the actual argument p in main - any changes to arr are not applied to p, so p is never set to point to the memory you just allocated.

What you will have to do is pass a pointer to p:

void doArr(int x, int y, int ***arr){
    *arr=(int **)malloc(sizeof(int *)*x); // note type of sizeof - you're allocating an array of int *, not int
    for (int i=0;i<y;i++){
      *(*arr+i)=(int *)malloc(sizeof(int)*y);
    }
}
...
doArr( 5, 2, &p );

Or, return arr and assign the result of doArr to p:

int **p = doArr( int x, int y )
{
  int **arr = malloc(...);
  ...
  return arr;
}

p = doArr( 5, 2 );

As Emanuel P notes, do is a keyword, so you can't use it as a function name.


A couple of style notes:

Since C89, malloc returns void * and does not require an explicit cast, and many of us will recommend against using it. It just adds visual noise and creates an extra maintenance burden.

Similarly, I often recommend that the operand of sizeof be your target expression, not a type name. Again, this eases your maintenance headaches if you change the type of the destination pointer.

Use array notation instead of pointer arithmetic where possible. It's easier to read and follow, and you're less likely to make a mistake.

Finally, always check the result of a malloc, calloc, or realloc call.

I'd rewrite your doArr function as follows:

void doArr(int x, int y, int ***arr)
{
  *arr = malloc( sizeof **arr * x ); 
  if ( *arr )
  {
    for ( int i = 0; i < y; i++ )
    {
      (*arr)[i] = malloc( sizeof *(*arr)[i] * y );
    }
  }
}

and call it as

doArr( 5, 2, &p );
John Bode
  • 119,563
  • 19
  • 122
  • 198
0

I want to do is create a dynamic 2D array

In your code you do not create a 2D array only the array of pointers.

void *doArr(size_t x, size_t y)
{
  int (*arr)[x][y] = malloc( sizeof((*arr)[0][0]) * x * y); 
  return arr;
}
0___________
  • 60,014
  • 4
  • 34
  • 74