From 19a6303205d070f62f2579168397579001a38fe5 Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Thu, 22 Mar 2012 19:50:36 -0500 Subject: [svn-r22128] Purpose: Fixed bug 4279 Description: Closed various HDF5 objects in DataSet::getInMemDataSize and Attribute::getInMemDataSize to remove some memory leaks. Platforms tested: Linux/32 2.6 (jam) Linux/64 2.6 (amani) SunOS 5.10 (linew) --- c++/src/H5Attribute.cpp | 24 ++++++++++++++-- c++/src/H5DataSet.cpp | 24 ++++++++++++++-- c++/test/dsets.cpp | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 6 deletions(-) diff --git a/c++/src/H5Attribute.cpp b/c++/src/H5Attribute.cpp index dad347f..84826c4 100644 --- a/c++/src/H5Attribute.cpp +++ b/c++/src/H5Attribute.cpp @@ -198,7 +198,7 @@ void Attribute::read(const DataType& mem_type, H5std_string& strg) const //-------------------------------------------------------------------------- size_t Attribute::getInMemDataSize() const { - char *func = "Attribute::getInMemDataSize"; + const char *func = "Attribute::getInMemDataSize"; // Get the data type of this attribute hid_t mem_type_id = H5Aget_type(id); @@ -207,7 +207,8 @@ size_t Attribute::getInMemDataSize() const throw AttributeIException(func, "H5Aget_type failed"); } - // Get the data type's size + // Get the data type's size by first getting its native type then getting + // the native type's size. hid_t native_type = H5Tget_native_type(mem_type_id, H5T_DIR_DEFAULT); if (native_type < 0) { @@ -219,7 +220,18 @@ size_t Attribute::getInMemDataSize() const throw AttributeIException(func, "H5Tget_size failed"); } - // Get number of elements of the attribute + // Close the native type and the datatype of this attribute. + if (H5Tclose(native_type) < 0) + { + throw DataSetIException(func, "H5Tclose(native_type) failed"); + } + if (H5Tclose(mem_type_id) < 0) + { + throw DataSetIException(func, "H5Tclose(mem_type_id) failed"); + } + + // Get number of elements of the attribute by first getting its dataspace + // then getting the number of elements in the dataspace hid_t space_id = H5Aget_space(id); if (space_id < 0) { @@ -231,6 +243,12 @@ size_t Attribute::getInMemDataSize() const throw AttributeIException(func, "H5Sget_simple_extent_npoints failed"); } + // Close the dataspace + if (H5Sclose(space_id) < 0) + { + throw DataSetIException(func, "H5Sclose failed"); + } + // Calculate and return the size of the data size_t data_size = type_size * num_elements; return(data_size); diff --git a/c++/src/H5DataSet.cpp b/c++/src/H5DataSet.cpp index 7351bbf..f73be0f 100644 --- a/c++/src/H5DataSet.cpp +++ b/c++/src/H5DataSet.cpp @@ -238,7 +238,8 @@ size_t DataSet::getInMemDataSize() const throw DataSetIException(func, "H5Dget_type failed"); } - // Get the data type's size + // Get the data type's size by first getting its native type then getting + // the native type's size. hid_t native_type = H5Tget_native_type(mem_type_id, H5T_DIR_DEFAULT); if (native_type < 0) { @@ -250,8 +251,19 @@ size_t DataSet::getInMemDataSize() const throw DataSetIException(func, "H5Tget_size failed"); } - // Get number of elements of the dataset - hid_t space_id = H5Dget_space(id); // first get its data space + // Close the native type and the datatype of this dataset. + if (H5Tclose(native_type) < 0) + { + throw DataSetIException(func, "H5Tclose(native_type) failed"); + } + if (H5Tclose(mem_type_id) < 0) + { + throw DataSetIException(func, "H5Tclose(mem_type_id) failed"); + } + + // Get number of elements of the dataset by first getting its dataspace, + // then getting the number of elements in the dataspace + hid_t space_id = H5Dget_space(id); if (space_id < 0) { throw DataSetIException(func, "H5Dget_space failed"); @@ -262,6 +274,12 @@ size_t DataSet::getInMemDataSize() const throw DataSetIException(func, "H5Sget_simple_extent_npoints failed"); } + // Close the dataspace + if (H5Sclose(space_id) < 0) + { + throw DataSetIException(func, "H5Sclose failed"); + } + // Calculate and return the size of the data size_t data_size = type_size * num_elements; return(data_size); diff --git a/c++/test/dsets.cpp b/c++/test/dsets.cpp index ee1a206..26abace 100644 --- a/c++/test/dsets.cpp +++ b/c++/test/dsets.cpp @@ -268,6 +268,77 @@ test_simple_io( H5File& file) } // test_simple_io /*------------------------------------------------------------------------- + * Function: test_datasize + * + * Purpose: Tests DataSet::getInMemDataSize(). + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Binh-Minh Ribler + * Thursday, March 22, 2012 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +test_datasize() +{ + + SUBTEST("DataSet::getInMemDataSize()"); + + int points[100][200]; + int check[100][200]; + int i, j, n; + + try + { + // Open FILE1. + H5File file(FILE1, H5F_ACC_RDWR, FileCreatPropList::DEFAULT, FileAccPropList::DEFAULT); + + // Open dataset DSET_SIMPLE_IO_NAME. + DataSet dset = file.openDataSet (DSET_SIMPLE_IO_NAME); + + // Get the dataset's dataspace to calculate the size for verification. + DataSpace space(dset.getSpace()); + + // Get the dimension sizes. + hsize_t dims[2]; + int n_dims = space.getSimpleExtentDims(dims); + + // Calculate the supposed size. Size of each value is int (4), from + // test_simple_io. + int expected_size = 4 * dims[0] * dims[1]; + + // getInMemDataSize() returns the in memory size of the data. + size_t ds_size = dset.getInMemDataSize(); + + // Verify the data size. + if (ds_size != expected_size) + { + H5_FAILED(); + cerr << " Expected data size = " << expected_size; + cerr << " but dset.getInMemDataSize() returned " << ds_size << endl; + throw Exception("test_compression", "Failed in testing DataSet::getInMemDataSize()"); + } + + PASSED(); + return 0; + } // end try + + // catch all dataset, space, plist exceptions + catch (Exception E) + { + cerr << " FAILED" << endl; + cerr << " <<< " << E.getDetailMsg() << " >>>" << endl << endl; + + return -1; + } +} // test_datasize + +/*------------------------------------------------------------------------- * Function: test_tconv * * Purpose: Test some simple data type conversion stuff. @@ -1004,6 +1075,10 @@ void test_dset() nerrors += test_compression(file)<0 ?1:0; nerrors += test_multiopen (file)<0 ?1:0; nerrors += test_types(file)<0 ?1:0; + + // Close the file before testing data size. + file.close(); + nerrors += test_datasize() <0 ? 1:0; } catch (Exception E) { -- cgit v0.12