Try to avoid using malloc and realloc as much as possible and use new
and zap(delete). But sometimes you may need to
use the "C" style memory allocations in "C++". Use the functions
my_malloc() ,
my_realloc() and
my_free().
These functions do proper allocations and initialisations and try to prevent
memory problems. Also these functions (in DEBUG mode) can keep track
of memory allocated and print total memory usage before and after the program
is run. This tells you if there are any memory leaks.
The my_malloc and my_realloc is defined as below. It allocates little more memory
(SAFE_MEM = 5) and initializes the space and if it cannot allocate it exits the
program. The 'call_check(), remove_ptr()' functions are active only
when DEBUG_MEM is defined in
makefile and are assigned to
((void)0) i.e. NULL
for non-debug production release. They enable the total-memory used tracing.
void *local_my_malloc(size_t size, char fname[], int lineno)
{
size_t tmpii = size + SAFE_MEM;
void *aa = NULL;
aa = (void *) malloc(tmpii);
if (aa == NULL)
raise_error_exit(MALLOC, VOID_TYPE, fname, lineno);
memset(aa, 0, tmpii);
call_check(aa, tmpii, fname, lineno);
return aa;
}
char *local_my_realloc(char *aa, size_t size, char fname[], int lineno)
{
remove_ptr(aa, fname, lineno);
unsigned long tmpjj = 0;
if (aa) // aa != NULL
tmpjj = strlen(aa);
unsigned long tmpqq = size + SAFE_MEM;
size_t tmpii = sizeof (char) * (tmpqq);
aa = (char *) realloc(aa, tmpii);
if (aa == NULL)
raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno);
// do not memset memset(aa, 0, tmpii);
aa[tmpqq-1] = 0;
unsigned long kk = tmpjj;
if (tmpjj > tmpqq)
kk = tmpqq;
for ( ; kk < tmpqq; kk++)
aa[kk] = 0;
call_check(aa, tmpii, fname, lineno);
return aa;
}
See
my_malloc.cpp.
and the header file
my_malloc.h.
for full implementation of the my_malloc program.
An example on usage of my_malloc and my_free as below:
char *aa;
int *bb;
float *cc;
aa = (char *) my_malloc(sizeof(char)* 214);
bb = (int *) my_malloc(sizeof(int) * 10);
cc = (float *) my_malloc(sizeof(int) * 20);
aa = my_realloc(aa, sizeof(char) * 34);
bb = my_realloc(bb, sizeof(int) * 14);
cc = my_realloc(cc, sizeof(float) * 10);
Note that in my_realloc you do not need to cast the datatype as the
variable itself is passed and correct my_realloc is called which
returns the proper datatype pointer. The my_realloc has overloaded
functions for char*, int* and float*.
In C/C++ Garbage Collection is not a standard feature and hence allocating
and freeing storage explicitly is difficult, complicated and is error-prone.
The Garbage Collection (GC) is not part of the C++ standard because there
are just so many ways how one could implement it; there are many
GC techniques, and deciding to use a particular one would not
be good for certain programs. Computer scientists had designed many GC
algorithms, each one of them catering to a particular problem domain.
There is no one single generic GC which will tackle all the problem domains.
As a consequence, GC is not part of C++ standard, they just left it out.
Still, you always have the choice of many freely available C++ libraries that do
the job for you.