diff --git a/include/trick/io_alloc.h b/include/trick/io_alloc.h index 9d2e26ce..b7882852 100644 --- a/include/trick/io_alloc.h +++ b/include/trick/io_alloc.h @@ -7,6 +7,14 @@ #include "trick/attributes.h" #include "trick/parameter_types.h" +/** +* enum TRICK_STCL - indicates whether or not the MemoryManager allocated the object. +* ------------------------------------------------------------------------------------------- +* TRICK_LOCAL - The memory manager allocated the object, via a form of declare_var..(). +* TRICK_EXTERN - The memory manager did not allocate the object, but was given a pointer to +* an object via a form of declare_extern_var..(). +* ------------------------------------------------------------------------------------------- +*/ typedef enum { TRICK_LOCAL = 0, TRICK_EXTERN = 1, diff --git a/trick_source/sim_services/MemoryManager/MemoryManager.cpp b/trick_source/sim_services/MemoryManager/MemoryManager.cpp index f6c5c497..801554da 100644 --- a/trick_source/sim_services/MemoryManager/MemoryManager.cpp +++ b/trick_source/sim_services/MemoryManager/MemoryManager.cpp @@ -89,8 +89,8 @@ Trick::MemoryManager::~MemoryManager() { io_src_delete_class( ai_ptr ); } } - free(ai_ptr->name); - free(ai_ptr->user_type_name); + if (ai_ptr->name) { free(ai_ptr->name); } + if (ai_ptr->user_type_name) { free(ai_ptr->user_type_name); } free(ai_ptr) ; } alloc_info_map.clear() ; diff --git a/trick_source/sim_services/MemoryManager/MemoryManager_declare_var.cpp b/trick_source/sim_services/MemoryManager/MemoryManager_declare_var.cpp index 7efc319a..6d4e9a2f 100644 --- a/trick_source/sim_services/MemoryManager/MemoryManager_declare_var.cpp +++ b/trick_source/sim_services/MemoryManager/MemoryManager_declare_var.cpp @@ -46,6 +46,7 @@ void* Trick::MemoryManager::declare_var( TRICK_TYPE type, char* allocation_name; int n_elems; Language language; + TRICK_ALLOC_TYPE allocation_type; void* address; ATTRIBUTES* sub_attr; ALLOC_INFO *new_alloc; @@ -126,6 +127,8 @@ void* Trick::MemoryManager::declare_var( TRICK_TYPE type, return ((void*)NULL); } language = Language_CPP; + /* io_src_allocate_class allocates objects using calloc (only). */ + allocation_type = TRICK_ALLOC_MALLOC; } else if ((type == TRICK_STRING) && (n_stars == 0 ) ) { @@ -157,6 +160,7 @@ void* Trick::MemoryManager::declare_var( TRICK_TYPE type, new_alloc->size = size; new_alloc->language = language; new_alloc->type = type; + new_alloc->alloc_type = allocation_type; if ((type == TRICK_STRUCTURED) || (type == TRICK_ENUMERATED)) { new_alloc->user_type_name = strdup( user_type_name.c_str()); diff --git a/trick_source/sim_services/MemoryManager/MemoryManager_delete_var.cpp b/trick_source/sim_services/MemoryManager/MemoryManager_delete_var.cpp index a68630df..cd5a17f8 100644 --- a/trick_source/sim_services/MemoryManager/MemoryManager_delete_var.cpp +++ b/trick_source/sim_services/MemoryManager/MemoryManager_delete_var.cpp @@ -38,6 +38,9 @@ int Trick::MemoryManager::delete_var(void* address ) { */ if ( alloc_info->stcl == TRICK_LOCAL ) { if ( alloc_info->alloc_type == TRICK_ALLOC_MALLOC ) { + + // This will call a destructor ONLY if alloc_info->type is TRICK_STRUCTURED. + // Otherwise it does nothing. io_src_destruct_class( alloc_info ); // The destructor that we just called MAY have deleted addresses diff --git a/trick_source/sim_services/MemoryManager/test/MM_delete_var.hh b/trick_source/sim_services/MemoryManager/test/MM_delete_var.hh new file mode 100644 index 00000000..e2ddebc5 --- /dev/null +++ b/trick_source/sim_services/MemoryManager/test/MM_delete_var.hh @@ -0,0 +1,13 @@ +/* +PURPOSE: (Testing) +*/ +#include + +class CountMe { +public: + int a; + static size_t count; + CountMe() { count ++; } + ~CountMe() { count --; } +} ; + diff --git a/trick_source/sim_services/MemoryManager/test/MM_delete_var_unittest.cc b/trick_source/sim_services/MemoryManager/test/MM_delete_var_unittest.cc index 41a4730a..50c61ae1 100644 --- a/trick_source/sim_services/MemoryManager/test/MM_delete_var_unittest.cc +++ b/trick_source/sim_services/MemoryManager/test/MM_delete_var_unittest.cc @@ -3,6 +3,8 @@ #include "trick/MemoryManager.hh" #include "MM_test.hh" #include +#include "MM_delete_var.hh" +size_t CountMe::count = 0; /* Test Fixture. @@ -21,6 +23,27 @@ class MM_delete_var_unittest : public ::testing::Test { ================================================================================ */ +TEST_F(MM_delete_var_unittest, CXX_object_constructor_destructor) { + + // =========================================================================================== + // This test determines: + // 1) whether a class's constructor is called when declare_var is called and, + // 2) whether a class's destructor is being called when delete_var is called. + // =========================================================================================== + + EXPECT_TRUE(std::is_pod::value == false); + + EXPECT_EQ(0, CountMe::count); + CountMe* cm1_p = (CountMe*)memmgr->declare_var("CountMe cm1"); + EXPECT_EQ(1, CountMe::count); + CountMe* cm2_p = (CountMe*)memmgr->declare_var("CountMe cm2"); + EXPECT_EQ(2, CountMe::count); + memmgr->delete_var("cm1"); + EXPECT_EQ(1, CountMe::count); + memmgr->delete_var("cm2"); + EXPECT_EQ(0, CountMe::count); +} + TEST_F(MM_delete_var_unittest, var_exists) { int exists; diff --git a/trick_source/sim_services/MemoryManager/test/Makefile b/trick_source/sim_services/MemoryManager/test/Makefile index 3f5708f3..77b50bf8 100644 --- a/trick_source/sim_services/MemoryManager/test/Makefile +++ b/trick_source/sim_services/MemoryManager/test/Makefile @@ -58,7 +58,8 @@ io_headers = MM_user_defined_types.hh \ MM_write_checkpoint.hh \ MM_get_enumerated.hh \ MM_ref_name_from_address.hh \ - MM_stl_testbed.hh + MM_stl_testbed.hh \ + MM_delete_var.hh # List of .cpp files produced by ICG from the io_headers. io_source = $(patsubst %.hh,io_%.cpp,$(io_headers)) @@ -119,6 +120,7 @@ $(TESTS) : %: %.o # ---------------------------------------------------------------------------------- # The following unittest programs are also dependent on the indicated object files. # ---------------------------------------------------------------------------------- +MM_delete_var_unittest : io_MM_delete_var.o MM_declare_var_unittest : io_MM_user_defined_types.o MM_declare_var_2_unittest : io_MM_user_defined_types.o MM_declare_extern_var_unittest : io_MM_user_defined_types.o