diff options
author | Allen Byrne <byrn@hdfgroup.org> | 2011-03-09 20:00:20 (GMT) |
---|---|---|
committer | Allen Byrne <byrn@hdfgroup.org> | 2011-03-09 20:00:20 (GMT) |
commit | 5b3223c7c569a3a20103c36ea8b38ae744033d2b (patch) | |
tree | 09ae2b7745a4c963c389fca86b3e3a4ae1f1d3ab /tools/lib/h5tools.c | |
parent | 2a492f23a1bfc25169dc6f063afaf6dd20d0e749 (diff) | |
download | hdf5-5b3223c7c569a3a20103c36ea8b38ae744033d2b.zip hdf5-5b3223c7c569a3a20103c36ea8b38ae744033d2b.tar.gz hdf5-5b3223c7c569a3a20103c36ea8b38ae744033d2b.tar.bz2 |
[svn-r20216] Valgrind fix for memory leak in h5tools_dump_xxx which is fixed by adding a new function;
htri_t H5Tdetect_vlen_str(hid_t tid) to h5tools. This needs to be called before any H5Aread/H5Dread and if TRUE, then call vlen_reclaim function after the corresponding h5tools_dump_xxx().
Tested: local linux and valgrind
Diffstat (limited to 'tools/lib/h5tools.c')
-rw-r--r-- | tools/lib/h5tools.c | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c index 00040ad..0286bea 100644 --- a/tools/lib/h5tools.c +++ b/tools/lib/h5tools.c @@ -622,6 +622,47 @@ h5tools_ncols(const char *s) } /*------------------------------------------------------------------------- + * Function: H5Tdetect_vlen_str + * + * Purpose: Recursive check for variable length string of a datatype. + * + * Return: TRUE if type conatains a variable string type, else FALSE + * + *------------------------------------------------------------------------- + */ +htri_t +H5Tdetect_vlen_str(hid_t tid) +{ + int n = 0; + htri_t has_vlen_str = FALSE; + H5T_class_t tclass = -1; + + if (H5Tis_variable_str(tid) == TRUE) + return TRUE; + + tclass = H5Tget_class(tid); + if (tclass == H5T_ARRAY) { + hid_t btid = H5Tget_super(tid); + has_vlen_str = H5Tdetect_vlen_str(btid); + H5Tclose(btid); + return has_vlen_str; + } + else if (tclass == H5T_COMPOUND) { + n = H5Tget_nmembers(tid); + for (int i = 0; i < n; i++) { + hid_t mtid = H5Tget_member_type(tid, i); + has_vlen_str = H5Tdetect_vlen_str(mtid); + if (has_vlen_str == TRUE) { + H5Tclose(mtid); + return TRUE; + } + H5Tclose(mtid); + } + } + return FALSE; +} + +/*------------------------------------------------------------------------- * Audience: Public * Chapter: H5Tools Library * Purpose: Emit a simple prefix to STREAM. @@ -1976,6 +2017,9 @@ h5tools_print_simple_subset(FILE *stream, const h5tool_format_t *info, h5tools_c hsize_t size_row_block; /* size for blocks along rows */ hsize_t row_counter = 0; + /* VL data special information */ + unsigned int vl_data = 0; /* contains VL datatypes */ + if ((size_t) ctx->ndims > NELMTS(sm_size)) H5E_THROW(FAIL, H5E_tools_min_id_g, "ndims and sm_size comparision failed"); @@ -1984,6 +2028,10 @@ h5tools_print_simple_subset(FILE *stream, const h5tool_format_t *info, h5tools_c size_row_block = sset->block.data[row_dim]; + /* Check if we have VL data in the dataset's datatype */ + if (H5Tdetect_vlen_str(p_type) == TRUE) + vl_data = TRUE; + /* display loop */ for (; hyperslab_count > 0; temp_start[row_dim] += temp_stride[row_dim], hyperslab_count--) { /* jump rows if size of block exceeded @@ -2067,6 +2115,10 @@ h5tools_print_simple_subset(FILE *stream, const h5tool_format_t *info, h5tools_c h5tools_dump_simple_data(stream, info, dset, ctx, flags, sm_nelmts, p_type, sm_buf); + /* Reclaim any VL memory, if necessary */ + if (vl_data) + H5Dvlen_reclaim(p_type, sm_space, H5P_DEFAULT, sm_buf); + if(H5Sclose(sm_space) < 0) H5E_THROW(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); if(sm_buf) @@ -2415,9 +2467,9 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, } /* Check if we have VL data in the dataset's datatype */ - if (H5Tdetect_class(p_type, H5T_VLEN) == TRUE) + if (H5Tdetect_vlen_str(p_type) == TRUE) vl_data = TRUE; - + /* * Determine the strip mine size and allocate a buffer. The strip mine is * a hyperslab whose size is manageable. |