[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 20010103: multi-dimensional array writes in c++



>To: address@hidden
>cc: address@hidden
>From: Bill Cassanova <address@hidden>
>Subject: multi-dimensional array writes in c++
>Organization: The Weather Channel
>Keywords: 200201031845.g03IgdN17359

Bill,

> I think I may have made mistake when I sent you original code snippet.
> Instead of a static float foo[10][10], the array is allocated
> with the c++ new operator.
> 
> So below instead of 
> float foo[10][10]
> 
> I had:
> float **foo = new float*[10];
> for( int i = 0; i < 10; i++ ){
>       foo[i] = new float[10];
> }
> 
> The rest is the same followed by an appropriate series of
> []deletes.

There is a significant difference between these two methods of
allocating memory for an array: with the first, a contiguous block of
memory for 100 floats is allocated, whereas with the second you are
allocating 10 blocks of 10 floats each but they will in general not be
contiguous in memory.  So in the first case, it is possible to put the
whole block of 100 values by just providing the starting address and
number of elements, whereas with the second method, you would need to
call put 10 times, once for each row.  Consider that with the second
method, you could make each row a different length (a "ragged" array),
but netCDF only understands rectangular arrays due to the constraint
that it has to support a Fortran interface.

> With this new information I have tried all of the methods suggested.
> What happens is the first 10 elements in the output netcdf file
> are correct, however after that point the values are trash.
> The only thing I have been able to get work is just creating
> the array statically and then doing the put.
> 
> I know your not in the business of checking everyones code but I think
> I am doing everything correctly.  Whether or not I have the array
> created statically or dynamiccally should really be immaterial or
> even unnoticed by the netCDF API.  I've attached the code itself
> too see if you notice anything else that could be of issue.  Look
> around line 537.  I've checked the values that are in the
> dynamic array and am sure they are correct prior to the put call
> so I am not sure what is happening.

The netCDF API for writing an array of values all at once to a netCDF
file requires that the block of data values be contiguous in memory.
The documentation for the nc_put_vara_ functions in the C interface
specifies the argument for the data as a:

   Pointer to a block of data values to be written. The order in which
   the data will be written to the netCDF variable is with the last
   dimension of the specified variable varying fastest.

In this respect, the C and C++ API are the same.  Admittedly, the
documentation could be more explicit about warning not to use
noncontiguous arrays for access.  I'll try to clarify that in the next
version.

If you need to allocate the array dynamically, you can do something
like this to make sure the data values are contiguous:

  float **foo = new float*[10];
  float *fooblock = new float[10*10]; //contiguous values needed
  for( int i = 0; i < 10; i++ ){
        foo[i] = fooblock + 10*i; // or &fooblock[10*i]
  }

--Russ