简体   繁体   中英

Assigning memory for contiguous 2D array

I am trying to create a generic function which when called allocated contiguous memory for a dimensional array. Goal is to achieve something like below

在此处输入图片说明

so to achieve it - equation I am using is

Type **pArray;
int total_elements = ((rows * cols) + rows); 
pArray = (Type **) malloc(total_elements * sizeof(Type));

I am also confused with respect to accessing elements part. I am finding it hard to visualize how below code will fill the elements of above array

for (row = 0; row < dim0; ++row)
   {
      for (col = 0; col < dim1; ++col)
      {
         /* For this to work Type must be a 1D array type. */
         for (ix = 0; ix < (int)(sizeof(item)/sizeof(item[0])); ++ix)
         {
            /*            printf("%4d\n", testValue); */
            ppObj[row][col][ix] = testValue;
            if (testValue == SCHAR_MAX)
               testValue = SCHAR_MIN;
            else
               ++testValue;
         }
      }
   } 

Goal is not to create below array format

在此处输入图片说明

This won't work. You assume your Type * has the same size as your Type which is most of the time not true. But, what do you need the row pointers for, anyway? My first implementation idea would be something like this:

typedef struct TypeArray
{
    size_t cols;
    Type element[];
} TypeArray;

TypeArray *TypeArray_create(size_t rows, size_t cols)
{
    TypeArray *self = calloc(1, sizeof(TypeArray) + rows * cols * sizeof(Type));
    self->cols = cols;
    return self;
}

write getter and setter using eg self->element[row * self->cols + row] .

[edit]: Following this discussion here it is doable like this:

typedef long long Type;


Type **createArray(size_t rows, size_t cols)
{
    size_t r;

    /* allocate chunk: rows times the pointer, rows * cols times the value */
    Type **array = malloc(rows * sizeof(Type *) + rows * cols * sizeof(Type));

    /* calculate pointer to first row: point directly behind the pointers,
     * then cast */
    Type *row = (Type *) (array + rows);

    /* set all row pointers */
    for (r = 0; r < rows; ++r)
    {
        array[r] = row;
        row += cols;
    }

    return array;
}

Usage could look like this:

int main()
{
    Type **array = createArray(3, 4);

    for (int r = 0; r < 3; ++r)
    {
        for (int c = 0; c < 4; ++c)
        {
            array[r][c] = (r+1) * (c+1);
        }
    }
    for (int r = 0; r < 3; ++r)
    {
        for (int c = 0; c < 4; ++c)
        {
            printf("array[%d][%d] = %lld\n", r, c, array[r][c]);
        }
    }

    free(array);
    return 0;
}

This assumes that no type needs a bigger alignment than a data pointer, otherwise you would have to calculate an amount of padding bytes to insert after your pointers. To be safe, you could use the sizeof(Type) and some modulo calculation for that (inserting the padding bytes using a char * pointer), but that would waste a lot of memory if your Type is for example a big struct .

All in all, this assignment is written by a really really clueless teacher.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM