| Synergex.com | Contact Us | Resource Center Login | Home
News & Events

A better way to implement dynamic memory


Back in 1996, Synergex released version 5.7.9 of Synergy Language, and with it, a powerful and very flexible feature known as dynamic memory. This feature immediately enabled Synergy developers to allow unrestricted processing of data. You no longer needed to pre-size arrays to hold order lines, transactions, etc. The data within the programs could then grow dynamically and was only restricted by the physical capabilities of the hardware hosting the runtime environment.

Many developers have utilized these capabilities throughout their code. The coding, however, can be confusing with the repeated use of ^M to reference data arrays and elements.  Many developers use parametric macros to simplify the code while editing it. This improves the readability of the code but presents problems when trying to debug, as the macros are not expanded in the debugger, and so developers need to refer back to the actual macro definitions and manually expand them.

All dynamic memory is accessed using the ^M function and referenced with the use of memory pointers. When you allocate memory, the function returns a pointer. To access the memory, you reference it via the returned pointer. And when processing is complete, you free the memory, again via the pointer. In the debugger, you can show what dynamic memory allocations are active by issuing the SHOW DYNMEM command. This command lists all allocated memory handles, the size of the allocated data, and the associated memory contents. For example,

DBG> show dynmem

GBL HANDLE 2 MEM_PROC segment size 11 data Hello World
GBL HANDLE 1 MEM_PROC segment size 8 data ~~~~~~~~

You can store any data within the allocated memory, including pointers to further allocations of dynamic memory. This is a very powerful capability and allows you to create dynamic arrays to hold any required data, including variable length strings. However, it is easy to introduce memory leaks at this point. The code segments below show how this can happen. 

Our requirement for the example program is to store an unknown number of variable length strings of data. To accomplish this, we create a dynamic memory array and in it store pointers to further dynamic memory segments that store the actual data.  The mainline program is very simple. It defines a variable that is used as a dynamic memory pointer. It then calls a routine several times to add variable amounts of data to each element of the array. We then call a routine to display the stored data to the screen. The mainline program looks like this:

Let’s take a look at the AddString() routine, which populates the dynamic memory array. It accepts an array memory pointer and the required string to add to the array. It then resizes the memory array, creates additional memory segments to hold the passed string, and holds the memory pointer to this string in the array.  Note that the code below will not compile because it includes continuation lines. To compile the code, just remove the line continuations and ensure that the code is on a single line:

We now have the ability to create the dynamic array and to hold variable length strings within it.  The final piece of the code is the DisplayString() subroutine, which displays the strings within the array. The code is shown below.  Again, to compile this code, you need to remove the line continuations and ensure that the code is on a single line:

As you can see, the use of the ^M function and all the subscripting makes for confusing code. The biggest problem, however, is in the mainline program. The final line of code releases the memory array, but it fails to release all the associated memory segments. In this mainline program, this would not be a serious issue because the next line terminates the program and causes the runtime to clean up all allocated memory. However, if this were a subroutine or program that was continually running in the background, then failure to correctly release all the allocated memory segments might cause the runtime to run out of memory and crash. To correct the problem, we need an additional routine to release the allocated memory segments:

In Synergy Language version 9, it is much easier to implement this functionality. With the introduction of the System.Collections.ArrayList class, you can very simply create dynamic arrays of objects or data. Also, with the addition of the System.String class, you can easily store variable length data. The modified source code is below. This example shows how to store simple strings in dynamic arrays; you can, of course, store more complex data types.

As you can see, the code is considerably simpler to write and to understand. There is no memory leak because the assignment of ^NULL to the array list ensures that any objects stored will be assigned to null. It’s also worth noting the omission of the XCALL statement in this example. With version 9, there is no requirement to use XCALL for subroutines or % for functions. For more information about these new features, search for “System.Collections.ArrayList” and “System.String” in the version 9 Synergy Language Reference Manual.

 

Contact Synergex to learn more about  News and Events
© 2008 Copyright Synergex | SiteMap