[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[netCDF #OPV-437501]: Reading 2D array in C, into array of pointers
- Subject: [netCDF #OPV-437501]: Reading 2D array in C, into array of pointers
- Date: Mon, 29 Nov 2010 12:37:42 -0700
Hi Tiago,
Sorry to have taken so long to respond to your question ...
> I am a great fan of NetCDF and used it extensively with the Fortran and
> Python interfaces, but now I must work with it in C. (This question may
> be related to my ignorance in C.)
The main difference is that Fortran uses column-major ordering (first
inde3x varies fastest), but C uses row-major (last index varies
fastest).
> I have a NetCDF file with a 4D variable. I would like to read a 2D slice
> of that variable into a (double **) array, called 'mm' and defined as:
>
> m = (double *) calloc(N * M, typeSize);
> mm = (double **) malloc(N* pointerSize);
>
> for(i=0; i< N; i++, mm += M)
> mm[i] = m;
>
> I know I can't read a 2D slice into it all at once because it is not
> contiguous.
It looks like it *is* contiguous, because you have allocated all N*M
doubles with a single call to calloc(). Then you have made m[1] point
to the ith row of doubles, but if you print out check the addresses,
you should be able to verify that mm[1][0] is the next double in
memory after mm[0][M-1], and in general the double mm[j+1][0]
immediately follows mm[j][M-1] in memory for any j in {0, 1, ...,
N-1}.
So you should be able to read a 2D slice into m, which is the same
as &m[0], which is the same as &mm[0][0].
> ... So I'm trying to read one column at once with nc_get_vara:
>
>
> for (i=0, i<N, i++){
> nc_get_vara_double(ncid,varid,start,count,mm[i]);
> start[0]++;
> }
I assume you have declared start and count as arrays of size 4
(because you are reading a 4D netCDF variable). I also assume you
have set
count[0] = M;
count[1] = count[2] = count[3] = 1;
and that the netCDF variable you are trying to read would have a CDL
declaration something like
double var(N, M, P, R);
with N and M the first two dimensions, used for "row" and "column".
If that's true, then the code above should read M values into the ith
row of the mm array, each time it's called.
> This compiles and when running it reads the first element of each row
> (i.e. mm[*][0]), but seems to put rubbish in all the other elements,
> which give a segfault when I try to access them. How do I read a 2D
> slice into a (double **) variable? I thought this would work as mm[i]
> is a pointer to a (double *) array. In the call to nc_get_vara_double
> I also tried putting &mm[i][0], but the result is the same...
If the assumptions I've spelled out above are correct, then this
should have worked, so I assume something is different, such as the
values of count.
> I can read the array using the uglier method of nc_get_var1_double in
> a M,N loop, but was looking for something more elegant and with less
> overhead.
Just reading in the whole 2D slice should be possible and is the most
elegant. You shouldn't have to read in each element separately!
--Russ
Russ Rew UCAR Unidata Program
address@hidden http://www.unidata.ucar.edu
Ticket Details
===================
Ticket ID: OPV-437501
Department: Support netCDF
Priority: Normal
Status: Closed