[MOAB-dev] r2568 - MOAB/trunk/tools/iMesh
kraftche at mcs.anl.gov
kraftche at mcs.anl.gov
Sat Jan 24 13:14:51 CST 2009
Author: kraftche
Date: 2009-01-24 13:14:51 -0600 (Sat, 24 Jan 2009)
New Revision: 2568
Modified:
MOAB/trunk/tools/iMesh/iMesh_MOAB.cpp
Log:
Fix iMesh_getAdjEntIndices
- fix bug using wrong size for array copy
- spec doesn't allow allocating return arrays larger than required size
so create temporaries instead
- fix memory leaks on failure (must free any arrays allocated on behalf
of the caller if not returning iBase_SUCCESS)
Modified: MOAB/trunk/tools/iMesh/iMesh_MOAB.cpp
===================================================================
--- MOAB/trunk/tools/iMesh/iMesh_MOAB.cpp 2009-01-24 17:05:22 UTC (rev 2567)
+++ MOAB/trunk/tools/iMesh/iMesh_MOAB.cpp 2009-01-24 19:14:51 UTC (rev 2568)
@@ -1159,6 +1159,10 @@
/*out*/ int* offset_size,
/*out*/ int *err)
{
+ const int allocated_entity_handles = (*entity_handles_allocated == 0);
+ const int allocated_indices = (*adj_entity_indices_allocated == 0);
+ const int allocated_offset = (*offset_allocated == 0);
+
// get source entities
iMesh_getEntities( instance,
entity_set_handle,
@@ -1172,77 +1176,102 @@
return;
// get adjacencies
- // If int and iBase_EntityHandle are the same size, put directly
- // into adj_entity_indices
- iBase_EntityHandle* temp_storage = 0;
- int size = 0;
- if (sizeof(int) == sizeof(iBase_EntityHandle)) {
- iMesh_getEntArrAdj( instance,
- *entity_handles, *entity_handles_size,
- entity_type_requested,
- reinterpret_cast<iBase_EntityHandle**>(adj_entity_indices),
- adj_entity_indices_allocated,
- adj_entity_indices_size,
- offset, offset_allocated, offset_size,
- err );
- temp_storage = reinterpret_cast<iBase_EntityHandle*>(*adj_entity_indices);
- size = *adj_entity_indices_size;
+ iBase_EntityHandle* all_adj_handles = 0;
+ int size = 0, alloc = 0;
+ iMesh_getEntArrAdj( instance,
+ *entity_handles, *entity_handles_size,
+ entity_type_requested,
+ &all_adj_handles, &alloc, &size,
+ offset, offset_allocated, offset_size,
+ err );
+ if (*err != iBase_SUCCESS) {
+ if (allocated_entity_handles) {
+ free( *entity_handles );
+ *entity_handles = 0;
+ *entity_handles_allocated = 0;
+ }
+ return;
}
- // Otherwise put result into new, temporary array and make sure
- // that adj_entity_indices can hold the same number of entries.
- else {
- int alloc = 0;
- iMesh_getEntArrAdj( instance,
- *entity_handles, *entity_handles_size,
- entity_type_requested,
- &temp_storage, &alloc, &size,
- offset, offset_allocated, offset_size,
- err );
- if (!*adj_entity_indices_allocated) {
- *adj_entity_indices = (int*)malloc(sizeof(iBase_EntityHandle)*size);
- if (!*adj_entity_indices) {
- *err = iBase_MEMORY_ALLOCATION_FAILED;
- return;
- }
+
+ // allocate or check size of adj_entity_indices
+ *adj_entity_indices_size = size;
+ if (allocated_indices) {
+ *adj_entity_indices = (int*)malloc(sizeof(iBase_EntityHandle)*size);
+ if (!*adj_entity_indices)
+ *err = iBase_MEMORY_ALLOCATION_FAILED;
+ else
*adj_entity_indices_allocated = size;
+ }
+ else if (*adj_entity_indices_allocated < size) {
+ *err = iBase_BAD_ARRAY_DIMENSION;
+ }
+ if (iBase_SUCCESS != *err) {
+ free( all_adj_handles );
+ if (allocated_entity_handles) {
+ free( *entity_handles );
+ *entity_handles = 0;
+ *entity_handles_allocated = 0;
}
- else if (*adj_entity_indices_allocated < size) {
- *err = iBase_BAD_ARRAY_DIMENSION;
- return;
+ if (allocated_offset) {
+ free( *offset );
+ *offset = 0;
+ *offset_allocated = 0;
}
- *adj_entity_indices_size = size;
+ return;
}
- if (*err != iBase_SUCCESS)
- return;
- // Put sorted unique version of temp array into final one
- // If input allocation is too small, need to use another temporary
+ // Now create an array of unique sorted handles from all_adj_handles.
+ // We need to create a copy because we still need all_adj_handles. We
+ // will eventually need to copy the resulting unique list into
+ // adj_entity_handles, so if adj_entity_handles is already allocated and
+ // of sufficient size, use it rather than allocating another temporary.
iBase_EntityHandle* unique_adj = 0;
- if (*adj_entity_handles_allocated == 0) {
- *adj_entity_handles_allocated = size;
- *adj_entity_handles = (iBase_EntityHandle*)malloc(sizeof(iBase_EntityHandle) * size);
+ if (*adj_entity_handles_allocated >= size) {
unique_adj = *adj_entity_handles;
}
- else if (*adj_entity_handles_allocated >= size) {
- unique_adj = *adj_entity_handles;
- }
else {
unique_adj = (iBase_EntityHandle*)malloc(sizeof(iBase_EntityHandle) * size);
}
- std::copy( temp_storage, temp_storage+size, unique_adj );
+ std::copy( all_adj_handles, all_adj_handles+size, unique_adj );
std::sort( unique_adj, unique_adj + size );
*adj_entity_handles_size = std::unique( unique_adj, unique_adj + size ) - unique_adj;
- // now copy data and relase temporary storage if necessary
+ // If we created a temporary array for unique_adj rather than using
+ // already allocated space in adj_entity_handles, allocate adj_entity_handles
+ // and copy the unique handle list into it
if (*adj_entity_handles != unique_adj) {
- if (*adj_entity_handles_allocated < *adj_entity_handles_size) {
+ if (!*adj_entity_handles_allocated) {
+ *adj_entity_handles = (iBase_EntityHandle*)malloc(
+ sizeof(iBase_EntityHandle) * *adj_entity_handles_size);
+ if (!*adj_entity_handles)
+ *err = iBase_MEMORY_ALLOCATION_FAILED;
+ else
+ *adj_entity_handles_allocated = *adj_entity_handles_size;
+ }
+ else if (*adj_entity_handles_allocated < *adj_entity_handles_size)
*err = iBase_BAD_ARRAY_DIMENSION;
- free(unique_adj);
- if ((int*)temp_storage != *adj_entity_indices)
- free(temp_storage);
+ if (iBase_SUCCESS != *err) {
+ free( unique_adj );
+ free( all_adj_handles );
+ if (allocated_entity_handles) {
+ free( *entity_handles );
+ *entity_handles = 0;
+ *entity_handles_allocated = 0;
+ }
+ if (allocated_offset) {
+ free( *offset );
+ *offset = 0;
+ *offset_allocated = 0;
+ }
+ if (allocated_indices) {
+ free( *adj_entity_indices );
+ *adj_entity_indices = 0;
+ *adj_entity_indices_allocated = 0;
+ }
return;
}
- std::copy( unique_adj, unique_adj + size, *adj_entity_handles );
+
+ std::copy( unique_adj, unique_adj + *adj_entity_handles_size, *adj_entity_handles );
free( unique_adj );
unique_adj = *adj_entity_handles;
}
@@ -1250,9 +1279,8 @@
// convert from adjacency list to indices into unique_adj
for (int i = 0; i < *adj_entity_indices_size; ++i)
(*adj_entity_indices)[i] = std::lower_bound( unique_adj,
- unique_adj + *adj_entity_handles_size, temp_storage[i] ) - unique_adj;
- if ((int*)temp_storage != *adj_entity_indices)
- free(temp_storage);
+ unique_adj + *adj_entity_handles_size, all_adj_handles[i] ) - unique_adj;
+ free( all_adj_handles );
}
More information about the moab-dev
mailing list