user4568389
user4568389

Reputation:

Mallocing a 2d array in C

I've been trying to create a 2d array of ints using a double pointer in C and I've created the following code. However, I don't understand why the statement a[1][1] is resulting in a segfault. At this point in my code rows has a value of 3 and so does cols. I'm positive that this is the section of code where the segfault is coming from. Does anyone know how to properly allocate a 2d array using double pointers and without a declaration like int[5][2].

int **a;
int **b;
int **c;
a = malloc(rows * sizeof(int *));
b = malloc(rows * sizeof(int *));
c = malloc(rows * sizeof(int *));

for (i = 0; i < rows; i++)
{
    a[i] = (int*) malloc(cols * sizeof(int));
}

for (i = 0; i < rows; i++)
{
    b[i] = (int*) malloc(cols * sizeof(int));
}

for (i = 0; i < rows; i++)
{
    c[i] = (int*) malloc(cols * sizeof(int));
}

a[1][1] = 5;

Upvotes: 0

Views: 355

Answers (2)

VolAnd
VolAnd

Reputation: 6407

Consider the following example (where allocIntArray and freeIntArray functions can be used for D2-arrayes of different sizes):

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

int ** allocIntArray(int nrows, int ncols)
// allocate memory for 2D array and returns pointer if successful or NULL if failed
{
    int r, c; // rows and cols counters
    int ** parray; // pointer to array
    // allocate memory for rows pointers
    parray = (int **) malloc(nrows * sizeof(int *));
    if( parray == NULL) // check
    {
        return NULL; // error sign
    }
    // allocate memory for each row
    for (r = 0; r < nrows; r++)
    {
        parray[r] = (int*) malloc(ncols * sizeof(int));
        if( parray[r] == NULL ) // check
        {
            // clean memory that was allocated before error
            while(--r >= 0)
            {
                free(parray[r]);
            }
            free(parray);
            return NULL; // error sign
        }
    }
    // return when success 
    return parray;
}

int freeIntArray(int nrows, int **parray)
// frees memory allocated for 2D array and returns 1 if successful or 0 if failed
{
    int r; // rows counter
    if( parray == NULL || nrows < 1)
    {
        return 0;
    }
    // free memory allocated for each row
    for (r = 0; r < nrows; r++)
    {
        if(parray[r] != NULL)
        {
            free(parray[r]);
        }
    }
    // free memory allocated for rows pointers
    free(parray);
    return 1;
}

int main()
{
    int ** myarray = allocIntArray(5, 6); // pointer to array

    // check that array allocated
    if(myarray == NULL)
    {
        printf("cannot allocat memory\n");
        return 1;
    }
    // work with array examples
    int c, r;
    // write values using pointer arithmetic
    for (r = 0; r < 5; r++)
    {
        for(c = 0; c < 6; c++)
        {
            *(*(myarray+r) + c) = r * 10 + c;
        }
    }
    // read values using usual 2-steps-indexing
    for (r = 0; r < 5; r++)
    {
        for(c = 0; c < 6; c++)
        {
            printf("%4d", myarray[r][c] );
        }
        printf("\n");
    }
    // free memory
    freeIntArray(5, myarray);
    return 0;
}

Upvotes: 1

VolAnd
VolAnd

Reputation: 6407

Your solution looks very complicated. I prefer the following for malloc-ing 2D array:

    int nrows = 5; // number of rows
    int ncols = 10; // number of columns
    int r, c; // rows and cols counters
    int ** parray = NULL; // pointer to array

    // allocate memory for rows pointers
    parray = (int **) malloc(nrows * sizeof(int *));
    if( parray == NULL) // check
    {
        return 1; // error
    }
    // allocate memory for each row
    for (r = 0; r < nrows; r++)
    {
        parray[r] = (int*) malloc(ncols * sizeof(int));
        if( parray[r] == NULL ) // check
        {
            return 2; // error
        }
    }
    // working with array (just an example
    for (r = 0; r < nrows; r++)
    {
        for(c = 0; c < ncols; c++)
        {
            parray[r][c] = r * 10 + c;
        }
    }

Upvotes: 0

Related Questions