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

Re: Re[2]: 20000710: netcdf nc_put_att_text bug?



>From: "Timothy E. Dowling" <address@hidden>
>Subject: netcdf nc_put_att_text bug?
>Organization: ?
>Keywords: 200007101335.e6ADZPT10374 netCDF nc_put_att_text

Tim,

> Thanks for answering so quickly.
>
> The problem arose from assigning units with
>
> #define VAR_NM_SZ 64
>
> nc_put_att_text(...,VAR_NM_SZ,"s");
>
> I expected that the double quotes would
> signal that the s (for seconds) and the following
> '\0' should be read from the input string, leaving 62 empty bytes, 
> or better yet, reducing len to the appropriate 2 in this case,
> but instead nc_put_att_text charged ahead, so my ncdump of
> the units was garbled with all sorts of impressive 
> source code or object code fragments in it after the "s". 
> Why I don't get a seg fault, I'm not sure, having apparently 
> earned one.  
>
> So, my issue is more of a write issue than a read issue, I think,
> such that the fortran access to all this would remain
> viable even if you stopped the c version of nc_put_att_text
> from charging past the '\0' when it reads my input
> string argument. 

Unfortunately, the nc_put_att_text function has no way of knowing
whether it was ultimately called from a C program or from a Fortran
program (since the Fortran interface is just a thin veneer over the C
interface).  It must depend on its length argument to specify how many
bytes are in the character attribute, which might have multiple '\0'
bytes in it.  The length of an attribute is stored in the netCDF file
with the attribute, so once you store it as 64, all programs that read
it from any of the languages you can use to read netCDF files (C, C++,
Fortran77, Fortran90, perl, python, ...) will expect the attribute to
be of length 64 and ncdump will also dump out all 64 characters.

> I seem to have fixed the problem by allocating a char buffer 
> with VAR_NM_SZ elements and filling it (every time) with '\0's before
> sprintf'ing it with my particular units for each variable.
> This produces clean units in the ncdump and keeps me from having to
> count individual unit-string-plus-1 lengths, but it isn't too pretty.
> I guess what I am suggesting is that the c version of nc_put_att_text
> could do this for me, or better yet, reduce len to string len+1.

I think it would be less work to just use something like

  nc_put_att_text(..., strlen("s") + 1, "s");

The time it takes to compute the length of a string is less than
the time you are now taking to fill the max length character buffer
with '\0's before call nc_put_att_text.  It's not a time-consuming
operation, so I would recommend using the strlen function.

> I hope a fortran read of what I have now will grab all the '\0's in a 
> harmless manner? Or is it potentially harmfull for s to 
> be s\0\0\0\0\0\0.... in the fortran context, in which case I
> really do need to count my string lengths?

There should be no particular problem with all those null bytes in the
Fortran context except that you will still have to identify the actual
length of the character attribute somehow in a Fortran program instead
of relying on the attribute length returned by the netCDF function.
But specifying the actual length of the string attributes with a call
to strlen as above would make this unnecessary, so reads in Fortran
would be simpler ...

--Russ