使用对malloc

时间:2016-02-13 20:48:29

标签: c arrays memory-management malloc contiguous

我必须动态分配一个连续的存储块来保存任意数据类型的2D数组 它只能使用malloc的一次通话 部分内存必须包含混合数据类型"指向数据类型的指针"和数据类型本身 任意数据类型称为Type。 完全披露:是的,这是一项任务。我已经在这上面打了30多个小时试图解决这个问题。我不能使用C99 +标准。它必须是Pre-C99。

到目前为止,我有这个:

Type **Create2D(size_t rows, size_t cols) {
    Type **ptr = (Type **)SafeMalloc(rows * sizeof(Type*) + rows * cols * sizeof(Type)); 
    //  rows*sizeof(Type*) is total memory needed for the elements to store the pointers. 
    //  rows*cols*sizeof(Type) is the memory needed to store the actual array data
    //  The sum of the above two gives the total amount of contiguous memory needed

    int index;
    for (index = 0; index < (int)rows; index++)
        ptr[index] = &ptr + rows*sizeof(Type *) + index * cols * sizeof(Type);
        //  in my mind, this assigns the pointers to the address of each column
        //  to the first address blocks allocated by malloc
}

Type数据类型由提供的头文件使用typedef定义,如下所示:

#define ELEMENTS 9
typedef signed char Type[ELEMENTS];
#undef ELEMENTS

SafeMalloc函数只包含错误检查以及malloc调用

static Type **SafeMalloc(size_t size) {
    void *vp;       
    if ((vp = malloc(size)) == NULL) {
        fputs("Out of memory\n", stderr);
        exit(EXIT_FAILURE);
    }
    return(vp);
}

我的Create2D函数从main调用如下,其中rowscols设置为for循环提供的变化值,以便它们通过列出的代码更改每次运行:

Type **ppobj;
int rows, cols;
ppobj = Create2D((size_t)rows, (size_t)cols);

这个数组在另一个循环中被调用和测试:

int x = Test2D(ppObj, rows, cols);

定义为:

int Test2D(Type **ppObj, int dim0, int dim1) {
    signed char testValue;
    int row, col, ix;       
    Type item;

    testValue = SCHAR_MIN;  
    for (row = 0; row < dim0; ++row) {
        for (col = 0; col < dim1; ++col) {
            for (ix = 0; ix < (int)(sizeof(item) / sizeof(item[0])); ++ix) {                
                ppObj[row][col][ix] = testValue;
                //  throws an exception in above step while stepping through at col = 1.
                if (testValue == SCHAR_MAX)
                    testValue = SCHAR_MIN;
                else
                   ++testValue;
            }
        }
    }
    ....
}

最后,我认为我所拥有的是接近的。给定1x27数组,它将通过它,但是当我调用释放内存的函数然后调用2x26数组时,它将在上面的步骤中出错。它已成为3x25阵列并且也在上面犯了错误。我的自由函数看起来像这样:

void Free2D(void *ptr) {
    free(ptr);
}

使用此sytax调用它,来自上面的主要功能:

Free2D((void *)ppObj);

我也经历了它并看到嵌套for循环中间的dim1变量从它传递的参数的设置值到1830342或者某些东西的巨大变化分类。这让我相信free()函数没有被我正确使用。

1 个答案:

答案 0 :(得分:3)

您的代码几乎正确,计算ptr[index]的公式不正确:您必须将ptr的字节偏移计算为字节指针。

这是一个更好的版本:

Type **Create2D(size_t rows, size_t cols) {
    Type **ptr = (Type **)SafeMalloc(rows * sizeof(Type*) + rows * cols * sizeof(Type)); 
    //  rows*sizeof(Type*) is total memory needed for the elements to store the pointers. 
    //  rows*cols*sizeof(Type) is the memory needed to store the actual array data
    //  The sum of the above two gives the total amount of contiguous memory needed

    size_t index;
    for (index = 0; index < rows; index++) {
        ptr[index] = (Type*)((unsigned char*)ptr + rows * sizeof(Type *) + index * cols * sizeof(Type));
       //  in my mind, this assigns the pointers to the address of each column
       //  to the first address blocks allocated by malloc
    }
    return ptr;
}

仍然存在潜在的对齐问题:Type可能需要比Type*更严格的对齐。为了解决这个问题,您可以单独计算索引大小,并将数据部分对齐为Type大小的倍数:

Type **Create2D(size_t rows, size_t cols) {
    size_t index_size = (size_t)((unsigned long long)(rows * sizeof(Type*)) * sizeof(Type) / sizeof(Type));
    Type **ptr = (Type **)SafeMalloc(index_size + rows * cols * sizeof(Type)); 
    //  index_size is total memory needed for the elements to store the pointers. 
    //  rows*cols*sizeof(Type) is the memory needed to store the actual array data
    //  The sum of the above two gives the total amount of contiguous memory needed

    size_t index;
    for (index = 0; index < rows; index++) {
        ptr[index] = (Type*)((unsigned char*)ptr + index_size + index * cols * sizeof(Type));
    }
    return ptr;
}