Click to See Complete Forum and Search --> : newbie C question


timfenn
December 29th, 2005, 01:47 PM
I'm still a bit new to C, and attempting to master pointers. I have a function that allocates a 2d pointer array, like so:


int main(int argc, char *argv[]){
float **data;

alloc_data(&data);
}

void alloc_data(float ***data){
int i, nx, ny;
float **tmp;

nx = 3;
ny = 3;

tmp = (float **) calloc(nx, sizeof(float *));
for (i=0; i<nx; i++)
tmp[i] = (float *) calloc(ny, sizeof(float));

*data = tmp;
}


works just fine, but how can I allocate data without having to alloc tmp and have data point to tmp? For example, if I do:


*data = (float **) calloc(nx, sizeof(float *));
for (i=0; i<nx; i++)
*data[i] = (float *) calloc(ny, sizeof(float));


it doesn't work as I expect - what am I missing here?

thanks for any help.

-Tim

evilsaltine
December 29th, 2005, 01:54 PM
[] has higher precedence than *, so the compiler interperets *data[i] as *(data[i]) when what you want is (*data)[i].

timfenn
December 29th, 2005, 01:57 PM
Aha! Thanks! Now I'll go learn my C precedence rules. ;)

-Tim

wildfrog
December 29th, 2005, 02:02 PM
Another way is to pass the double pointer as a reference:

void alloc_data(float** &data) // pass reference (to the double pointer)
{
int i, nx, ny;

nx = 3;
ny = 3;

data = (float **) calloc(nx, sizeof(float *));
for (i=0; i<nx; i++)
data[i] = (float *) calloc(ny, sizeof(float));
}

int main(int argc, char *argv[])
{
float **data;
alloc_data(data);
}

- petter

Eli Gassert
December 29th, 2005, 02:09 PM
I agree with Wildfrog; that is the method of choice in my opinion :)

NoHero
December 29th, 2005, 02:28 PM
I agree with Wildfrog; that is the method of choice in my opinion :)

The only problem: C++ might understand references, but C does not. The OP stated to use C so your solution won't help him at all.

wildfrog
December 29th, 2005, 02:40 PM
The only problem: C++ might understand references, but C does not. The OP stated to use C so your solution won't help him at all.Oh, I thought he was just another lazy C++ programmer (and dropped the obvious ++) :rolleyes:

Well, then I'd go for evilsaltines solution:

void alloc_data(float*** data) // pass pointer (to the double pointer)
{
int i, nx, ny;

nx = 3;
ny = 3;

*data = (float **) calloc(nx, sizeof(float *));
for (i=0; i<nx; i++)
(*data)[i] = (float *) calloc(ny, sizeof(float));
}

int main(int argc, char *argv[])
{
float **data = 0;
alloc_data(&data);
}

- petter

timfenn
December 29th, 2005, 03:30 PM
The code is currently in C, but I am fiddling a bit with C++ as well, so thanks for pointing out the handy pointer reference trick for C++.

-Tim