chris
chris

Reputation: 5006

C reshape 1d to 2d

I want to reshape an array of length L to one of MxN, however rather than create new memory by copying the elements over in for loops I'd like to do some pointer casting to allow me to access the array with double subscripting (array[X][Y]) .

I've googled around for ages and couldn't find anything helpful.

Any help would really be appreciated.

EDIT: The array of interest is on the heap not stack.

Upvotes: 0

Views: 188

Answers (4)

PeterT
PeterT

Reputation: 8284

By the way if you want it super dynamic (as in no sizes are known at compile-time) you can do this by not copying all the values but by creating an index for the 2nd dimension like so:

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

const int FULL = 100;
const int X = 10;
const int Y = 10;

int *dim1;
int **nested;

int main(void) {
    dim1 = malloc(sizeof(int)*FULL);
    nested = malloc(sizeof(int*)*X);
    for(int i=0; i<X;i++)
    {
        nested[i] = &dim1[Y*i];
    }
    dim1[15] = 42;
    printf("nested[1][5]: %d",nested[1][5]);

    free(nested);
    free(dim1);
    return 0;
}

Upvotes: 0

Paul R
Paul R

Reputation: 213170

unions are your friends:

#include <stdio.h>

#define M 5
#define N 4

typedef union {
    int a1[M * N];
    int a2[M][N];
} U;

int main()
{
    U u;
    int i, j;

    for (i = 0; i < M * N; ++i)
    {
        u.a1[i] = i;
    }

    for (i = 0; i < M; ++i)
    {
        for (j = 0; j < N; ++j)
        {
            printf("%8d", u.a2[i][j]);
        }
        printf("\n");
    }

    return 0;
}

Upvotes: 2

Paul R
Paul R

Reputation: 213170

typedefs are your friends:

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

#define M 5
#define N 4

typedef int Array1D[M * N];
typedef int Array2D[M][N];

int main()
{
    Array1D *a1 = malloc(sizeof(*a1));
    Array2D *a2 = (Array2D *)a1;
    int i, j;

    for (i = 0; i < M * N; ++i)
    {
        (*a1)[i] = i;
    }

    for (i = 0; i < M; ++i)
    {
        for (j = 0; j < N; ++j)
        {
            printf("%8d", (*a2)[i][j]);
        }
        printf("\n");
    }

    free(a1);

    return 0;
}

Note: above code has now been updated to use heap allocation so as not to break strict aliasing rules.

Upvotes: 0

downhillFromHere
downhillFromHere

Reputation: 1977

Pointer casting doesn't seem like a good idea here. But if the number of columns is known before run-time, one option I often encounter is to simply define a macro e.g.

#define arrayName(i,j) arrayName[((i)*N) + (j)]

Or

 #define ELEMENT(arrayName, i,j) (arrayName)[((i)*N) + (j)]

if you want it to be more flexible.

Upvotes: 4

Related Questions