Assigning the value of 2D array element using (int**) pointer results in EXC_BAD_ACCESS

72 views Asked by At

I am a MacOS user and I want to write a function in C that assigns every element of a 2 dimensional (dynamically allocated) array a value of 0. But when I compile and run the program an error message

Exception has occurred. EXC_BAD_ACCESS (code=1, address=0x0)

pointing to the statement arr[i][j] = 0; appears.

#include <stdlib.h>
#include <stdio.h>
#define SIZE 8

/* assigns 0 to all elements of 2d array */
void clearArr(int **arr, int rows, int columns)
{
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < columns; j++)
        {
            arr[i][j] = 0;
        }
    }
}

int main(void)
{
    int **arr = (int**)malloc(sizeof(int) * (size_t)SIZE);

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

    clearArr(arr, SIZE, SIZE);

    for (int i = 0; i < SIZE; i++)
    {
        free(arr[i]);
    }
    free(arr);

    return 0;
}

Substituting it for "((arr + i) + j) = 0;" doesn't solve the problem.

2

There are 2 answers

0
gulpr On

You do not have 2D array only array of pointers. I would suggest using array pointers instead.

void clearArr(size_t rows, size_t cols, int (*arr)[cols] )
{
    for (size_t i = 0; i < rows; i++)
    {
        for (size_t j = 0; j < cols; j++)
        {
            arr[i][j] = 0;
        }
    }
}

void RandomArr(size_t rows, size_t cols, int (*arr)[cols] )
{
    for (size_t i = 0; i < rows; i++)
    {
        for (size_t j = 0; j < cols; j++)
        {
            arr[i][j] = rand() % 10000;
        }
    }
}

void printArr(size_t rows, size_t cols, int (*arr)[cols] )
{
    for (size_t i = 0; i < rows; i++)
    {
        for (size_t j = 0; j < cols; j++)
        {
            printf("% 5d ", arr[i][j]);
        }
        printf("\n");
    }
}


int main(void)
{
    srand(time(NULL));

    size_t rows = rand() % 30;
    size_t cols = rand() % 30;

    int (*arr)[cols] = malloc(rows * sizeof(*arr));

    if(arr)
    {
        RandomArr(rows, cols, arr);
        printArr(rows, cols, arr);
    }

    free(arr);
    return 0;
}

https://godbolt.org/z/o7ddfqnfc

Your code is invalid as you do not allocate the correct ammount of memory. You should:

int **arr = malloc(sizeof(*arr) * SIZE);
2
Vlad from Moscow On

There is a typo in this line

int **arr = (int**)malloc(sizeof(int) * (size_t)SIZE);
                          ^^^^^^^^^^^

You are allocting an array of pointers. So you need to write

int **arr = (int**)malloc(sizeof(int *) * (size_t)SIZE);
                          ^^^^^^^^^^^^

Also casting to the type size_t the integer constant SIZE is redundant. You could just write

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

Pay attention to that you could use another approach to allocate memory that would simplify setting elements of allocated arrays to zero.

Here you are

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

#define SIZE 8

int main(void)
{
    int **arr = malloc( SIZE * sizeof( *arr ) );

    arr[0] = calloc( SIZE * SIZE, sizeof( *arr[0] ) );

    for (int i = 1; i < SIZE; i++)
    {
        arr[i] = arr[i-1] + SIZE;
    }

    free( arr[0] );
    free(arr);

    return 0;
}

Or if instead of calloc to use malloc

arr[0] = malloc( SIZE * SIZE * sizeof( *arr[0] ) );

then to set elements of the array to zero you could write

memset( arr[0], 0, size * size * sizeof( int ) );

Alternatively you can at once allocate a two-dimensional array like

int ( *arr )[SIZE] = malloc( sizeof( int[SIZE][SIZE] ) );

and again you could use memset to set all elements to zero

memset( arr, 0, size * size * sizeof( int ) );