Home

Memory Allocation and Deallocation

by Spatial Moderator Spatial Moderator on 04-18-2008 02:18 AM - last edited on 04-18-2008 02:33 AM


Here’s an excerpt from the new R19
Documentation describing allocation and deallocation, based on the term “alloc”
being highly searched on Faces & Facets.

 

Allocating and De-allocating ACIS Memory



This article introduces you to one means of allocating and de-allocating
memory in an ACIS based application, using the ACIS memory management system
for all allocations and de-allocations. This is the preferred means for new
users because it provides a consistent and efficient approach for all
allocations and de-allocations. Additional information on the ACIS memory
management system is available in the Memory Management section of the documentation.


Local Variables 

 

Temporary (locally scoped) variables are created on the stack. The creation
of these non-persistent variables follows standard C++ conventions. This
applies to ACIS specific classes as well as standard types. These allocations
(and subsequent automatic de-allocations) are handled by the operating system
and do not utilize the ACIS memory management system.



The allocation of local variables is demonstrated below. The SPAvector class
is the ACIS implementation of a generalized vector class and is used quite
extensively within ACIS.


{

  double value1 = 4.0;

  double value2 = 2.5;

 

  SPAvector vec1(value1, 0.0, 0.0);

  SPAvector vec2(0.0, value2, 0.0);

  SPAvector vec3  = vec1 * vec2;  // The cross product

  double dot_prod = vec1 % vec2;  // The dot product

}

 


Persistent Variables

Persistent variables are created on the Free Store or heap. Allocations and

de-allocations of persistent variables are handled by the ACIS memory management
system. These variables may be created on an ACIS free list. (The use of free
lists depends on whether or not free lists are created during ACIS
initialization and whether or not a free list of the appropriate size for the
given object exists.)



In order to direct allocations and de-allocations of persistent variables to
the ACIS memory management system two macros are used to allocate and
de-allocate memory: ACIS_NEW and ACIS_DELETE. These macros are
used instead of the standard operator new( ) and operator delete( ).
Every source file that uses ACIS should include the acis.hxx header
file. One of the benefits of including this header file is the definitions of
all of the macros for memory allocation and de-allocation are included.

 

 
Construction and Destruction of ENTITIES

Most ENTITIES will be constructed for you by calling API and direct
interface functions; however, occasionally you may need to construct an
instance of a class derived from ENTITY in your application. In this case you
will use the ACIS_NEW macro rather than the operator new( ). An
example of this is shown below.



SPAposition my_loc(0.0, 0.0, 0.0);

APOINT * pt = ACIS_NEW APOINT(my_loc);

VERTEX * vert = ACIS_NEW VERTEX(pt);

 

Because ENTITIES are maintained by the ACIS history mechanism to facilitate
roll back and roll forward (i.e., undo and redo) you will typically not
de-allocate the memory for an ENTITY; instead you will call either the lose( )
method of the ENTITY or a higher level function that calls the lose( ) method
for you. The reason for calling a higher level function is because you often
want to lose a set of connected ENTITIES. For example, you would not want to
manually call lose( ) for each of the topological, geometrical, and
application-specific ENTITIES in a complex BODY. You would want to call a
single function that traverses the data structure and calls lose( ) for you. In
addition, many types of ENTITIES are use counted, so you do not want to call
lose( ) directly on them.



There are two higher level functions that are typically called to lose
ENTITIES:

 

 

         API Function                                                     Description
api_delent(ENTITY*,...)                Deletes a topological ENTITY and all subentities.
api_del_entity(ENTITY*,...)         Deletes a topological ENTITY and all connected entities.

 

 

The difference between these two functions is very significant. api_delent()

loses the given topological entity, any associated geometrical entity, any
associated application-specific entities on the given entity, and then
traverses the topological structure downward, losing all lower level
topological entities and their associated geometric and application-specific
entities. api_del_entity( ) loses the given topological entity, any associated
geometrical entity, any associated application-specific entities on the given
entity, and then traverses the data structure upward, downward, and
horizontally, losing all connected entities. If entities in one BODY point to
entities in another BODY, all entities in both BODIES will be lost. Neither
function can affect pointers in your application that pointed to the lost
entities. It is the responsibility of the application programmer to be sure
that no dangling pointers remain. The use of api_delent( ) and api_del_entity(
) are demonstrated below.



SPAposition my_loc(0.0, 0.0, 0.0);

APOINT * pt = ACIS_NEW APOINT(my_loc);

VERTEX * vert = ACIS_NEW VERTEX(pt);

api_delent (vert);

vert = NULL;

pt = NULL;

 

BODY * my_block = NULL;

api_make_cuboid (10.0, 10.0, 10.0, my_block);

api_delent (my_block);

my_block = NULL;

Construction and Destruction of non-ENTITY classes

Instances of objects that are not derived from ENTITY should be constructed

and destructed using the ACIS_NEW and ACIS_DELETE operators. This ensures
consistent use of the underlying allocation and de-allocation functions. Use of
ACIS_NEW and ACIS_DELETE to construct and destruct instances of classes not
derived from ENTITY is demonstrated below.

SPAposition * my_loc_ptr = ACIS_NEW SPAposition(10.0, 10.0, 10.0);

ACIS_DELETE my_loc_ptr;

 


Construction and Destruction of Standard Types

The use of the ACIS_NEW macro when constructing a standard type object (for
instance, a double or int) causes the memory allocation to be processed by the
ACIS memory manager. When destructing an instance of a standard type that was
constructed with ACIS_NEW one should always use the STD_CAST macro with
ACIS_DELETE. This is demonstrated below.



double * double_ptr = ACIS_NEW double;

ACIS_DELETE STD_CAST double_ptr;

 


Construction and Destruction of Arrays

When destructing an array of objects one should always use [ ] with
ACIS_DELETE just as with operator delete( ). This is demonstrated below.

SPAposition * pos_array = ACIS_NEW SPAposition[NUM_LOCS];

ACIS_DELETE [] pos_array;

 

int * i_array = ACIS_NEW int[NUM_INTS];

ACIS_DELETE [ ] STD_CAST i_array;

 

Static Variables


Because the ACIS memory management system has not been initialized when
static objects are constructed, you should not create instances of ACIS classes
as static variables in your application.



 


Message Edited by Stacey on 04-18-2008 03:33 AM

Comments
by Entity Spatial Employee on 04-21-2008 08:28 AM
Good job, Stacey. Let me just add that pointers are also standard types, even when they point to non-standard types. So something like this

SPAposition** my_loc_ptr_ptr = ACIS_NEW SPAposition*[NUM_PTRS];

is freed as follows:

ACIS_DELETE [] STD_CAST my_loc_ptr_ptr;

-John-
by on 04-30-2008 02:00 AM
Hi Stacey,
in your post you mention something that I always wondered about but never managed to ask:
You say: "If entities in one BODY point to entities in another BODY ..."
I don't know if we ever had the situation but does that mean, that Acis supports sharing of entities between bodies, e.g. surfaces? Sharing of topological entities is likely impossible, I assume...
Thomas
by menexis on 04-05-2009 04:08 PM
Nice post Stacey!!