Sign in to follow this  
Scribe

calloc 2d arrays

Recommended Posts

Scribe    106
Hi guys, I need to create dynamic 2d arrays of 'short unsigned int's using calloc. I've tried quite a few methods but none have worked without error. Can anybody suggest a good method that works, and hopefully post an example? Thanks.

Share this post


Link to post
Share on other sites
DrEvil    1148
I would suggest allocating a 2d array as a 1d array,
unsigned short *pArray = new unsigned short[width*height];

Then accessing it using a macro or inline function

int index(int x, int y)
{
return x * width + y;
}

The reason this is better that dynamically allocating a 2d array is because the memory in this case will all be contiguous, and therefore alot better for caching, as opposed to each row being spread out on the heap as in the case with this:

unsigned short **array2d;
array2d = new unsigned short *[width];
for(int i = 0; i < height; ++i)
{
array2d[i] = new unsigned short[height];
}

Not to mention the creation and cleanup process of this 2nd method is longer and more of a pain, when you can just do delete [] pArray, instead of looping through each row and deleting the row, then finally deleting the first array.

Share this post


Link to post
Share on other sites
tychon    652
I have to agree with DrEvil on this. It's much easier to just think of it as a 2D array but deal with it as a 1D than it is to actually hassle with a 2D array. However, if you really must, here is a basic example of a 2D array. No error checking, which I do recommend you include in your own implementation.

(Been awhile since I've actually played with C, spot me if there's any errors.)

#include <cstdio>
#include <cstdlib>
#include <ctime>

int main() {
srand(time(0));

int** dArray = (int**)calloc(sizeof(int*) * 10, sizeof(int*));

for (int n = 0; n < 10; ++n)
dArray[n] = (int*)calloc(sizeof(int) * 10, sizeof(int));

for (int y = 0; y < 10; ++y)
for (int x = 0; x < 10; ++x)
dArray[y][x] = rand() % 256;

printf("%d %d\n", dArray[0][5], dArray[5][0]);

for (int n = 0; n < 10; ++n)
free(dArray[n]);
free(dArray);

return 0;
}

Share this post


Link to post
Share on other sites
snk_kid    1312
Quote:
Original post by tychon
(Been awhile since I've actually played with C, spot me if there's any errors.)


It kinda shows in the code [wink][lol].

calloc takes the number of elements and the size of each element so your example wasn't quite correct. As a side note calloc also initializes each byte to zero which isn't alway desirable.

Also your trying to include C++ style headers, they don't exist in pure C [wink].

I also don't like that way of creating dynamic multidimensional arrays elements are not stored contiguously (only the columns/rows are), i'd either do it the 1d way and computing indices like you guys where saying or if i really wanted syntactic sugar but still have elements stored contiguously:


#include <stddef.h> // size_t
#include <stdlib.h> // malloc, free
#include <stdio.h> // printf
#include <math.h> // rand

int main() {

size_t rows = 3, cols = 4;

int* buf = malloc(sizeof(int) * (rows * cols));
int** arr = malloc(sizeof(int*) * rows);

for(size_t i = 0, j = 0; i < rows; j += cols, ++i)
*(arr + i) = &buf[j];

for(size_t i = 0; i < rows; ++i)
for(size_t j = 0; j < cols; ++j)
arr[i][j] = rand();


for(size_t i = 0; i < rows; ++i)
for(size_t j = 0; j < cols; ++j)
printf("%i\n", arr[i][j]);

free(arr);
free(buf);
}


You can use realloc for your shrinking/growing purposes.

i'd recommend using an expotentional growth strategy for good overall preformance, growing by one element at a time generally is naive but it does depend on the context how-ever.

[Edited by - snk_kid on June 10, 2005 10:22:11 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this