I’m not sure what I’m doing wrong, because I thought I was following the rules, but the following small program fails with a segfault:
#include "hdf5.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc __attribute__((unused)), char **argv __attribute__((unused)))
{
/* Create a new property list. */
hid_t const fprop = H5Pcreate(H5P_FILE_ACCESS);
assert(fprop > 0);
hid_t const classID = H5Pget_class(fprop);
assert(classID > 0);
char * buf = H5Pget_class_name(classID);
assert(buf != NULL);
printf("%s\n", buf);
free(buf);
H5Pclose(fprop);
return 0;
}
The reference manual clearly states, " The pointer to the name must be freed by the user after each successful call."
Running under the debugger, I get a backtrace which indicates the segfault was caused by the call to free()
; if I run with valgrind, I get the following complaint:
==60068== Invalid free() / delete / delete[] / realloc()
==60068== at 0x4C2ACDD: free (vg_replace_malloc.c:530)
==60068== by 0x400B35: main (test-get_class_name.c:24)
==60068== Address 0x75a1b00 is 48 bytes inside a block of size 68 alloc'd
==60068== at 0x4C29BE3: malloc (vg_replace_malloc.c:299)
==60068== by 0x5177DCE: H5MM_malloc (H5MM.c:292)
==60068== by 0x51782F0: H5MM_xstrdup (H5MM.c:465)
==60068== by 0x525C982: H5P_get_class_name (H5Pint.c:5033)
==60068== by 0x51FDEF7: H5Pget_class_name (H5P.c:1574)
==60068== by 0x400AF9: main (test-get_class_name.c:21)
==60068==
==60068==
==60068== Process terminating with default action of signal 6 (SIGABRT)
==60068== at 0x5F281F7: raise (in /usr/lib64/libc-2.17.so)
==60068== by 0x5F298E7: abort (in /usr/lib64/libc-2.17.so)
==60068== by 0x5F21265: __assert_fail_base (in /usr/lib64/libc-2.17.so)
==60068== by 0x5F21311: __assert_fail (in /usr/lib64/libc-2.17.so)
==60068== by 0x5177BFA: H5MM_final_sanity_check (H5MM.c:232)
==60068== by 0x4E7CF66: H5_term_library (H5.c:403)
==60068== by 0x5F2BA68: __run_exit_handlers (in /usr/lib64/libc-2.17.so)
==60068== by 0x5F2BAB4: exit (in /usr/lib64/libc-2.17.so)
==60068== by 0x5F14C0B: (below main) (in /usr/lib64/libc-2.17.so)
There seem to be three possibilities:
- The HDF5 code and documentation are correct, but I’m doing something wrong and/or interpreting the documentation incorrectly.
- The HDF5 code is correct, but the documentation is wrong and I should not free the buffer.
- The documentation is correct and I should free the buffer, but the HDF5 code is incorrect.
Note that removal of the free()
call results in an abort()
with the following complaint:
test-get_class_name: /home/greenc/work/cet-is/test-products/hdf5/v1_10_2_snap10/source/hdf5-1.10.2-snap10/src/H5MM.c:232: H5MM_final_sanity_check: Assertion `0 == H5MM_curr_alloc_bytes_s' failed.
Help!