为连续的2D阵列分配内存

时间:2015-07-26 20:17:22

标签: c arrays multidimensional-array malloc

我正在尝试创建一个泛型函数,当为维度数组调用分配的连续内存时。目标是实现类似下面的内容

enter image description here

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

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

目标创建以下数组格式

enter image description here

1 个答案:

答案 0 :(得分:1)

这不会奏效。您认为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]

[edit] :在此讨论后, 可以这样做:

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 *指针插入填充字节),但是这会浪费很多的内存您的Type例如是一个大struct

总而言之,这项任务是由一位非常真正无能的老师写的。