连续的内存块与malloc

时间:2010-02-12 09:13:25

标签: c pointers malloc

我正在尝试在一个函数调用中创建一个连续的内存块,该函数调用将内存的第一部分作为指向其他块的指针数组。基本上,我正在尝试:

int **CreateInt2D(size_t rows, size_t cols)
{
    int **p, **p1, **end;
    p = (int **)SafeMalloc(rows * sizeof(int *));
    cols *= sizeof(int);
    for (end = p + rows, p1 = p; p1 < end; ++p1)
        *p1 = (int *)SafeMalloc(cols);
    return(p);
}

void *SafeMalloc(size_t size)
{
    void *vp;

    if ((vp = malloc(size)) == NULL) {
        fputs("Out of mem", stderr);
        exit(EXIT_FAILURE);
    }
    return(vp);
}

但有一个街区。就我而言:

int *Create2D(size_t rows, size_t cols) {
 int **memBlock;
 int **arrayPtr;
 int loopCount;
    memBlock = (int **)malloc(rows * sizeof(int *) + rows * cols * sizeof(int));
    if (arrayPtr == NULL) {
        printf("Failed to allocate space, exiting..."); 
        exit(EXIT_FAILURE);
    }
    for (loopCount = 1; loopCount <= (int)rows; loopCount++) {
        arrayPtr = memBlock + (loopCount * sizeof(int *));
        //I don't think this part is right.  do I need something like arrayPtr[loopCount] = ....
    }
 return(memBlock);
}

4 个答案:

答案 0 :(得分:1)

像这样的东西

 int **Create2D(size_t rows, size_t cols) 
 {
    size_t cb = (rows * sizeof(int *)) + (rows * cols * sizeof(int));
    int * pmem = (int *)SafeMalloc(cb);

    int ** prows = (int **)pmem; 
    int * pcol = (int *)&prows[rows]; // point pcol after the last row pointer

    for (int ii = 0; ii < rows; ++ii)
    {
       prows[ii] = pcol;
       pcol += cols;
    }

    return prows;
}

答案 1 :(得分:1)

您似乎无法准确了解自己想要的内容 实现。 记录它!它会清理你的思绪,除非你不理解,否则没有人会, 像这样的代码是一个维持的噩梦(甚至在时间适用于你自己 经过)。

要创建一个分配连续内存块的函数,必须使用将使用的内存总量仅调用一次SafeMalloc。

/*
 * Memory layout example for 2 rows and 3 cols
 *
 *                      1 1 1 1 1 1 1 1 1 1
 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |P|P|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|
 * |1|2|1|1|1|2|2|2|3|3|3|1|1|1|2|2|2|3|3|3|
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *
 * P1 is a pointer coloum data for row 1, points to memory start + offset 2 (assuming sizeof(int) == sizeof(int *))
 * P2 is for row 2, points to memory start + offset 11
 * C1 is coloumn 1 data, etc
 */
int **CreateInt2D(size_t rows, size_t cols)
{
        int **memory_start, **p1, *col_data;
        size_t total_memory_to_allocate;

        total_memory_to_allocate = rows * sizeof(int *) + rows * cols * sizeof(int);
        memory_start = (int **) SafeMalloc(total_memory_to_allocate);

        for (col_data = (int *)(memory_start + rows), p1 = memory_start;
             p1 < (int **)col_data;
             ++p1, col_data += cols * sizeof(int))
                *p1 = col_data;

        return memory_start;
}

此示例基于尽可能接近原始版本,John Knoeller使用数组订阅的答案可能是更好的方法。

答案 2 :(得分:0)

我不太清楚你要做什么,但你的最后一段代码是错误的。您针对NULL测试arrayPtr但从未分配它。在for()循环中,您分配给arrayPtr但实际上并没有对它执行任何操作。

如果您正在寻找使用单个内存块的2D数组,那么问题出在哪里:

int* array = (int*)malloc(rows * count * sizeof(int));
int* someCellPtr = &array[y * rows + x];

答案 3 :(得分:0)

如果您想要使用一个alloc的2D数组,可以使用calloc

int** p2DArray = (int**)calloc(rows,cols * sizeof(int));

或只是malloc:

int** p2DArray = (int**)malloc(rows * cols * sizeof(int));

这允许正常索引:

int nCellValue = p2DArray[row][col];
int* pCell = &p2DArray[row][col];