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.
- It's already developed.
- It's tested.
- It's intuitive/readable without using a macro.
- It's extensible.
- 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?
malloc
ing 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 memmove
s.
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.
精彩评论