[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[netCDF #RST-674955]: minor bugs in netCDF version 3.5 for C
- Subject: [netCDF #RST-674955]: minor bugs in netCDF version 3.5 for C
- Date: Thu, 15 Mar 2007 11:19:53 -0600
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