Reputation: 17164
I want to allocate memory dynamically using malloc
so that i can use for loop to access each array and array element.
My code looks like this:
long naxes1[3] = {1,1,1}, naxes2[3] = {1,1,1}, naxes3[3] = {1,1,1}, naxes4[3] = {1,1,1}; //upto naxes20
Another line of code is:
double *pix1, *pix2, *pix3, *pix4, *pix5; //upto *pix20
To allocate the memory, I do this:
pix1 = (double *) malloc(npixels * sizeof(double));
pix2 = (double *) malloc(npixels * sizeof(double));//20 times,
How can we use for loop to allocate memory for pixels instead of this?
moreover,
#include"cfitsio.h"
long npixels = 1;
fits_read_pix(names[0], TDOUBLE, firstpix, npixels, NULL, pix1, NULL, &status)
here, names[i] are names of fitsfile inputs, TDOUBLE is double type, first pixels, npixels, etc are local variables inside C library routine cfitsio.h
Upvotes: 1
Views: 99
Reputation: 1013
You likely did a lot of copying and pasting to come up with that code. Well let's use that systematic logic of yours and separate out repeated logic, with the aid of some 2D arrays:
long naxes[20][3];
const long naxes_init[3] = {1, 1, 1};
for (int i = 0; i < 20; ++i)
{
memcpy(naxes[i], naxes_init, 3 * sizeof (long));
}
double *pix[20];
for (int i = 0; i < 20; ++i)
{
pix[i] = (double *) malloc(npixels * sizeof(double));
}
You already have most of the logic down: you just need to understand for-loop syntax. After all, the line in the second loop is almost exactly what you had copied 20 times earlier.
Lastly, a key difference is that of course C uses 0-based indices... and so should you. e.g. pix[0]
is the equivalent to your pix1
.
Upvotes: 1
Reputation: 754090
When you have written variable names naxes1
, naxes2
, …, naxes20
, you need to rewrite the code to use an array. If you need indexes 1..20
, then you could write:
int naxes[21][3] = { { -1, -1, -1 }, /* Element 0 - unused */
{ 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 },
{ 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 },
{ 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 },
{ 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 },
{ 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 },
};
Or, using a very sensible and convenient GCC extension:
int naxes[21][3] = { [0] = { -1, -1, -1 }, [1 ... 20] = { 1, 1, 1 }, };
The range notation [1 ... 20]
is the extension; the [0] = { -1, -1, -1 },
is standard C99 — a designated initializer.
With this, you can use naxes[n][m]
for n
in the range 1..20
and m
in the range 0..2
to access the elements of naxes
.
Similar comments apply to the pixN
variables. However, there you want dynamic memory allocation; you might then use:
double *pix_base = malloc(20 * npixels * sizeof(double));
if (pix_base == 0) { …handle out of memory error… }
double pix[21];
pix[0] = 0;
for (int i = 1; i < 21; i++)
pix[i] = pix_base + (i - 1) * npixels;
You can now use pix[n][m]
for n
in the range 1..20
and m
in the range 0..(npixels-1)
to access the data. When finished, you call free(pix_base)
to free all the memory at once. This is more economical on space than 20 separate memory allocations (and more economical on calls to malloc()
and free()
).
You can adapt this second technique to handle the arrays of integers too.
If you can use entries 0..19 instead of 1..20, then you can save a little complexity.
Upvotes: 2
Reputation: 224082
How about this:
double *pix[20];
int i;
for (i=0;i<20;i++) {
pix[i] = calloc(npixels, sizeof(double));
if (pix[i] == NULL) {
perror("calloc failed");
exit(1);
}
}
I'm using calloc
instead of malloc
because the former is geared toward creating an array, and has the side effect of initializing all bytes to zero.
Upvotes: 0