The default behavior of GLib in Linux is such that in case of a memory allocation failure, the GLib memory allocation API will call abort and hence terminate the application.
Memory allocation failures are more likely on a mobile device and aborting
the application in such cases is undesirable. Therefore, the implementation
of GLib for Symbian platform has been modified so that the GLib memory allocation
APIs return NULL and do not call abort()
. This requires the
application written using GLib to start handling memory allocation failures
which they are currently not doing.
If the user, for example, wants to change the first character of a string with z and return the string to the caller a GLib code for this can be written as follows:
gchar * f1(gchar * x) { gchar *temp; temp = g_strdup(x); temp[0] = ‘z’; return temp; }
If there is a memory allocation failure in Linux, the call to g_strdup
which
internally uses g_malloc
will cause the application to abort.
However, in Symbian platform the g_malloc()
function will
return NULL, but the implementation of g_strdup()
is such
that the return value of g_malloc()
is not checked for NULL.
This causes the g_strdup()
API to panic or crash the application.
Thus, a mechanism to deal with the failures, panics or crash resulting from
low memory situations within Symbian platform is needed.
The user needs to initialize the framework which handles the low memory scenarios using the below-mentioned macros:
SET_LOW_MEMORY_TRAP(failure_value)
: This
macro will set a trap handler for low memory cases. In case there is an allocation
failure, the failure value will be returned from the function where the trap
handler is set.
SET_LOW_MEMORY_TRAP_VOID()
: This
will do the same as the above except that the function where this is set will
just return. This will typically be used by functions which return void. In
this case, however, the caller must check the errno
value.
If it is ENOMEM
, then the user must handle things appropriately.
REMOVE_LOW_MEMORY_TRAP()
: This
will remove the trap handler which was set.
The function f1()
will now be rewritten as:
#include <glowmem> gchar * f1(gchar * x) { gchar *temp; SET_LOW_MEMORY_TRAP(NULL); temp = g_strdup(x); temp[0] = ‘z’; REMOVE_LOW_MEMORY_TRAP(): return temp; }
If there is a memory allocation failure when the above function f1()
is
called, then f1()
will return NULL to its caller. The caller
of f1()
is expected to check the failure value of f1()
instead
of ignoring the same.
Some words of caution: The
macro SET_LOW_MEMORY_TRAP()
defines a variable so it is necessary
to make the call after all the local variables declarations in C. REMOVE_LOW_MEMORY_TRAP()
must
be called just before the return from the function, which means that if there
are four return statements in the function then all of them must be preceded
with a call to REMOVE_LOW_MEMORY_TRAP()
.