mirx
mirx

Reputation: 626

Dynamic memory allocation - 2 dimensional array

I have some troubles understanding pointers and dynamic memory allocation. I wrote those 2 codes:

    int **array;
    array = malloc(nrows * sizeof(int *));
    if(array == NULL)
    {
        fprintf(stderr, "out of memory\n");
        return -1;
    }
        for(i = 0; i < nrows; i++)
    {
        *(array+i) = malloc(ncolumns * sizeof(int));
        if(array[i] == NULL)
        {
            fprintf(stderr, "out of memory\n");
            return -1;
        }
    }

and:

    int **array;
    array = malloc(nrows * sizeof(int *));
    if(array == NULL)
    {
        fprintf(stderr, "out of memory\n");
        return -1;
    }
        for(i = 0; i < nrows; i++)
    {
        array[i] = malloc(ncolumns * sizeof(int));
        if(array[i] == NULL)
        {
            fprintf(stderr, "out of memory\n");
            return -1;
        }
    }

They should allocate space for 2 dimensional array. Although Im not sure if theyre both correct, I mean: does this line:

array[i] = malloc(ncolumns * sizeof(int));

do the exact same thing line this one:

*(array+i) = malloc(ncolumns * sizeof(int));

?

Upvotes: 1

Views: 604

Answers (4)

Anis_Stack
Anis_Stack

Reputation: 3442

int **array;
array = malloc(nrows * sizeof(int *));

the variable array is an array of pointer or double pointer variable. the value of these pointers are done in the next array allocation :

array[i] = malloc(ncolumns * sizeof(int)); or 
*(array+i) = malloc(ncolumns * sizeof(int));

array [i]==> i is the index of array witch contain the value of pointer allocated by malloc(ncolumns * sizeof(int));

*(array + i) ==> is the offset using to parse array and *array + i) is the value of pointer allocated by malloc(ncolumns * sizeof(int));

so

array[i] = malloc(ncolumns * sizeof(int));
and 
*(array+i) = malloc(ncolumns * sizeof(int));

are exactly the same

Upvotes: 1

John Bode
John Bode

Reputation: 123458

Both *(array + i) and array[i] evaluate to the same thing (assuming that one is a pointer and the other an integer). For your sanity and everyone else's, use the second form; it'll be easier to read and maintain.

If you know the size of your array dimensions at compile time, or if you are working with a compiler that supports variable-length arrays, you can simplify this a bit:

int (*array)[ncols] = malloc( sizeof *array * nrows );

This will allocate enough memory for an nrows x ncols array of int. If you're working with a compiler that does not support variable-length arrays, then ncols must be known at compile time (i.e., it must be a macro or other compile-time constant). You would access array elements as you would for any regular 2D array:

array[i][j] = x;

One advantage this method has over the two-step method is that all the memory is allocated contiguously; that is, all the rows will be adjacent in memory. This can matter if you want to treat the array as a single continuous blob of data (such as if you're sending it over a socket via a write system call). With the two-step method, it's not guaranteed that all the rows will be adjacent.

The other advantage is that deallocation only requires a single call to free:

free( array );

Upvotes: 2

CodyAntcliffe
CodyAntcliffe

Reputation: 59

Yes, they should all be treated the same when you compile your code.

Upvotes: 2

HelloWorld123456789
HelloWorld123456789

Reputation: 5359

Yes.

array[i], *(array+i) and i[array] are treated as same things by the compiler.

Upvotes: 3

Related Questions