Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

B = &A[0][0]; ??? if A is dynamically allocated 1

Status
Not open for further replies.

zub44

Programmer
Dec 18, 2003
7
0
0
US
I would like to have a 1D pointer point to a M by N 2D dynamically allocated array. If the 2D is a constant array, everything works fine:


main()
{
int i, j;
double *b, A[3][2];

for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++)
A[j] = 1.0;

b = &A[0][0];
}
/* b = 1.0 1.0 1.0 1.0 1.0 1.0 */


This works OK.
I think malloc allocates more memory than it needs because if A is now dynamically allocated, ..

main()
{
int i, j;
double *b, **A;

A = (double **) malloc(3*sizeof(double *) );
for (i = 0; i < 3; i++)
A = (double *) malloc(2*sizeof(double ) );

for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++)
A[j] = 1.0;

b = &A[0][0];
}
/* b = 1.0 1.0 0.0 1.0 1.0 0.0 */
^ ^


Why are those 0's there? Is there a way where I can make a 1D pointer point to a NxM 2D allocated array?


Thanks
 
Arrays are contiguous, which is why it is generally (though not strictly) OK to flatten them.
A[0][N-1] is immediately before A[1][0].

The way you dynamically allocate them, which is correct if you want to preserve some sense of 2D subscripts is completely wrong if you also want to flatten it.
A[0][N-1] has no relationship to A[1][0] since they result from different malloc calls.

The immediate problem is solved by doing
Code:
b = malloc( 2 * 3 * sizeof(double) );
This is all contiguous memory, so you can treat it as such using whatever array flattened code you have elsewhere.

If you also want to treat it as a 2D array, then things get a little bit trickier.
Here's an example
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ROWS    2
#define COLS    3

void show_flattened ( int *a ) {
    int j;
    for ( j = 0 ; j < ROWS * COLS ; j++ ) printf(&quot;%d &quot;, a[j] );
    printf(&quot;\n&quot;);
}

int main() {
    int A[ROWS][COLS] = { { 1, 2, 3 }, { 4, 5, 6 } };
    int  *a;    /* flattened 2D array */
    int **pa;   /* real 2D array */
    int **pb;   /* another real 2D array */
    int r, c;
    
    /* allocate the real 2D array - this you know already */
    pb = malloc( ROWS * sizeof *pb );
    for ( r = 0 ; r < ROWS ; r++ ) {
        pb[r] = malloc( COLS * sizeof *pb[r] );
        for ( c = 0 ; c < COLS ; c++ ) {
            pb[r][c] = A[r][c];
        }
    }
    
    /* allocate flattened 2D array */
    a = malloc( ROWS * COLS * sizeof *a );

    /* now make a 2D array out of it */
    pa = malloc( ROWS * sizeof *pa );
    for ( r = 0 ; r < ROWS ; r++ ) {
        pa[r] = &a[ COLS * r ];
        for ( c = 0 ; c < COLS ; c++ ) {
            pa[r][c] = A[r][c];
        }
    }

    /* a[0] and pa[0][0] are the same memory location */
    printf( &quot;%p %p\n&quot;, (void*)&a[0], (void*)&pa[0][0] );
    show_flattened( &A[0][0] );
    show_flattened( &a[0] );
    show_flattened( &pa[0][0] );
    /* pb isn't contiguous, so you cant do this */
    return 0;
}

--
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top