开发者

Dynamic 2D Array allocation in C

How I should allocate dynamic arrays in C? Currently I have a function I wrote called malloc2D that looks like this:

void* malloc2D(size_t unitSize, uint firstCount, uint secondCount)
{
    void** pointer = malloc(sizeof(id) * firstCount);
开发者_运维知识库    for (int i =0; i < firstCount; i ++){
        pointer[i] = malloc(unitSize * secondCount);
    }
    return pointer;
}

It works fine however I have been told that it puts a lot of strain on the memory allocating separately. What is the best or most conventional way to do this?


You could allocate the entire block at once:

int ** foo;

foo = malloc(sizeof(int*) * firstCount);
foo[0] = malloc(sizeof(int) * firstCount * secondCount);
for (int i=1; i<firstCount; i++)
{
    foo[i] = foo[0] + i * secondCount;
}


My suggestion would be to keep what you have.

  1. It's already developed.
  2. It's tested.
  3. It's intuitive/readable without using a macro.
  4. It's extensible.
  5. No bottleneck has quantitatively been identified.

Sometimes trying to optimize when there is not a problem can hurt performance. Have you done any benchmarks against your friends theory?

mallocing a big chunk requires locating contiguous address space, and might even cause malloc to fail when your current method would succeed (address space fragmentation, etc).

When I said your current implementation is extensible, I mean it is trivial to resize. Should you allocate for a [100][3] and later realize you need a [100][4] then all you need to do is 100 very small reallocs, likely not changing addresses. However, should the macro method need resizing, you need to realloc the whole chunk which may not exist contiguously. Even worse, the data is no longer in the right place to be accessed by the macro because the math has changed, so you will need a series of expensive memmoves.

To generalize, I think it is important to always code with readability, maintainability, and ease of use in mind - and only optimize away from that after establishing a bottleneck.


You can allocate the array as a contiguous bloc like this. Suppose you want ints:

int (*arr)[secondCount] = malloc( sizeof(int[firstCount][secondCount]) );

You could hide this behind a macro which takes the typename as a macro argument, although the code is simple enough that that is not really necessary.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜