'Segmentation Fault C Arrays and Malloc

I am trying to initialize an arary using a function but I feel like theres something not right about it. When I compile it I am getting Segmentation Fault but not sure where about. Can someone point me in the right direction where I got wrong. I mean if theres a better way to do it feel free to comment. Thank you.

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

void initialize(int ** arr, int row, int col)
{
    int i; 

    arr = (int **) malloc(sizeof(int *) *col);
    for(i = 0; i < row; i++)
    {
        arr[i] = (int *) malloc(sizeof(int) * row); 
    }

}

void freeArray(int ** arr)
{
    free(arr);
}


int main()
{
    int **arr;
    int r, c; 

    initialize(arr, 3,6); 

    for(r = 0; r <= 3; r++)
    {
        for(c = 0; c <= 6; c++)
        {
            printf("%d ", arr[r][c] = r*c);
        }
        printf("\n");
    }

    freeArray(arr);
}


Solution 1:[1]

For starters the function has a bug.

void initialize(int ** arr, int row, int col)
{
    int i; 

    arr = (int **) malloc(sizeof(int *) *col);
    for(i = 0; i < row; i++)
    {
        arr[i] = (int *) malloc(sizeof(int) * row); 
    }

}

Instead of using the variable col in this statement

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

you have to use the variable row

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

And in this statement instead of using the variable row

arr[i] = (int *) malloc(sizeof(int) * row); 

you have to use the variable col

arr[i] = (int *) malloc(sizeof(int) * col); 

As for the main problem then the function accepts the pointer declared in main by value. It means that the function deals with a copy of the pointer. Changes of the copy do not reflect on the original pointer.

Either you need to pass the pointer to the function indirectly through a pointer to it (passing by reference) like

void initialize(int *** arr, int row, int col)
{
    int i; 

    *arr = (int **) malloc(sizeof(int *) *row);
    for(i = 0; i < row; i++)
    {
        ( *arr )[i] = (int *) malloc(sizeof(int) * col); 
    }

}

and the function is called like

initialize( &arr, 3,6);

Or it is better when the function allocates arrays and returns a pointer to the arrays like

int ** initialize( int row, int col)
{
    int **arr;

    arr = (int **) malloc(sizeof(int *) *row);
    for( int i = 0; i < row; i++)
    {
        arr[i] = (int *) malloc(sizeof(int) * col); 
    }

    return arr;
}

and the function is called like

int **arr = initialize( 3, 6 );

Also in the nested for loops in main there are used invalid conditions

for(r = 0; r <= 3; r++)
{
    for(c = 0; c <= 6; c++)
    {
        printf("%d ", arr[r][c] = r*c);
    }
    printf("\n");
}

You have to write

for(r = 0; r < 3; r++)
{
    for(c = 0; c < 6; c++)
    {
        printf("%d ", arr[r][c] = r*c);
    }
    printf("\n");
}

Also the function freeArray must be declared and defined the following way

void freeArray(int ** arr, int row)
{
    if ( arr != NULL )
    {
        for ( int i = 0; i < row; i++ )
        {
            free( arr[i] );
        }
    }

    free( arr );
}

and called like

freeArray(arr, 3);

Pay attention to that in general you need to check whether memory was successfully allocated before using pointers that point to dynamically allocated memory.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1