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

[netCDF #RST-674955]: minor bugs in netCDF version 3.5 for C



Hi Ulrich,

Thanks for sending in the bug report.

With regards to the first problem, you are right, the nc_get_att_text() 
function does not provide null termination of the attribute string it returns.  
This is the documented behavior, and I can understand why you might think it's 
a bug.  However, netCDF is supposed to be language-independent, and in 
particular, a file you are reading with the C interface may have been written 
from a Fortran program.  Attributes are really arrays of characters rather than 
strings, in order to accommodate Fortran as well as C.  The documentation and 
examples recommend explicitly adding the null termination to attributes before 
using them as strings.  One other reason for this is the use of conventions to 
store multiple strings in a single attribute.  In that case, it might be 
required to have multiple '\0' characters separating the string values.  Also, 
if we automatically added the '\0' at the end of character attributes, it would 
be more likely to overwrite allocated memory, since the lengt!
 h returned by nc_inq_attlen() does not include any trailing byte, as the 
documentation for nc_inq_attlen() explains:

   For attributes of type NC_CHAR, you should not assume that this includes a 
trailing zero byte; it doesn't if the attribute was stored without a trailing 
zero byte, for example from a FORTRAN program. Before using the value as a C 
string, make sure it is null-terminated.

As regards the second "bug", I think it is actually an error in use of 
nc_put_var_double() which I will try to explain. First, note the warning in the 
documentation on using this simplest interface with record variables:

Take care when using the simplest forms of this interface with record variables 
when you don't specify how many records are to be written. If you try to write 
all the values of a record variable into a netCDF file that has no record data 
yet (hence has 0 records), nothing will be written. Similarly, if you try to 
write all of a record variable but there are more records in the file than you 
assume, more data may be written to the file than you supply, which may result 
in a segmentation violation.
http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c.html#nc_005fput_005fvar_005f-type
 

In the test program you sent, you first create the file "netCDF_file1.nc" with 
no data in it, then write a single data value in corresponding to rh[3][2][3], 
which writes into the fourth record (the first record is rh[0][*][*]).  After 
writing this value, the netCDF file has 4 records, so the subsequent write of 
the entire variable 

  /* write values into netCDF variable */
  status = nc_put_var_double(ncid, rh_id, rh_array);

will attempt to write 4 records, each with 100 values, and 400 doubles will be 
written.

Then the program creates a second empty file, "netCDF_file2.nc", and writes a 
single value corresponding to rh[1][2][3].  Since this value would be in the 
second record, the file now has two records.  The subsequent write of the 
entire rh variable

  /* write values into netCDF variable */
  status = nc_put_var_double(ncid, rh_id, rh_array);

writes 2 records of 100 values each, or 200 values.  When I compile and run the 
program, it behaves as expected, writing 400 values in the first file and 200 
values in the second file.  If you really want to write 400 values in the 
second file, you need to use the more complex interface:

  int nc_put_vara_double(int ncid, int varid, const size_t start[],
                            const size_t count[], const double *dp);

which lets you explicitly specify how many records to write, rather than just 
using the current number of records in the file.

--Russ


Russ Rew                                         UCAR Unidata Program
address@hidden                     http://www.unidata.ucar.edu



Ticket Details
===================
Ticket ID: RST-674955
Department: Support netCDF
Priority: High
Status: Closed