为连续的二维数组分配内存

Assigning memory for contiguous 2D array

我正在尝试创建一个通用函数,该函数在调用时会为维数组分配连续内存。目标是实现如下

所以要实现它 - 我使用的等式是

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

我也对访问元素部分感到困惑。我发现很难想象下面的代码将如何填充上面数组的元素

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;
         }
      }
   } 

目标是而不是创建以下数组格式

这行不通。您假设 Type * 的大小与 Type 的大小相同,但在大多数情况下这是不正确的。但是,无论如何,您需要行指针做什么?我的第一个实现想法是这样的:

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;
}

写 getter 和 setter 使用例如self->element[row * self->cols + row].

[编辑]: 在此处进行讨论之后 可以这样操作:

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;
}

用法可能如下所示:

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;
}

这假定没有类型需要比数据指针更大的对齐方式,否则您将不得不计算要在指针后插入的填充字节数。为了安全起见,您可以使用 sizeof(Type) 和一些模计算(使用 char * 指针插入填充字节),但这会浪费 lot如果你的 Type 是一个大的 struct.

总而言之,这个作业是真的真的没脑子的老师写的。