28.3
malloc and free
In C++, you use the new operator to get memory from the heap
and use delete to return the memory.
C has no built-in memory-handling operations. Instead, it makes use
of two library routines:
malloc
and free.
28.3.1 The C malloc function
The function malloc takes a single
parameter—the number of bytes to allocate—and returns a
pointer to them (as a char * or void
*). But how do we know how big a structure is?
That's where the sizeof operator
comes in. It returns the number of bytes in a structure. To allocate
a new variable of type struct foo in C, we use the
code:
foo_ptr = (struct foo *)malloc(sizeof(struct foo));
Note that we must use a cast to turn the pointer returned by
malloc into something useful. The C++ syntax for
the same operation is much cleaner:
foo_ptr = new foo;
Suppose we want to allocate an array of three structures. We need to
multiply our allocation size by three, resulting in the following C
code:
foo_ptr = (struct foo *)malloc(sizeof(struct foo) * 3);
The much simpler C++ equivalent is:
foo_ptr = new foo[3];
|
The function calloc
is similar to malloc except that it takes two
parameters: the number of elements in the array of objects and the
size of a single element. Using our array of three
foos example, we get:
foo_var = (struct foo*)calloc(3, sizeof(foo));
The other difference is that calloc initializes
the structure to zero. Thus, the C++ equivalent is:
foo_var = new foo[3];
memset(foo_var, '\0', sizeof(foo) * 3);
|
Programs can freely mix C-style malloc and C++
new calls. The C
memory
allocators are messy, however, and should be converted to their C++
version whenever possible.
There are a number of traps concerning C-style memory allocation.
Suppose we take our structure foo and turn it into
a class. We can, but shouldn't, use the C memory
routines to allocate space for the class:
class foo {...};
foo_var = (struct foo *)malloc(sizeof(struct foo)); // Don't code like this
Because C++ treats struct as a special form of
class, most compilers won't
complain about this code. The problem is that our
malloc statement allocates space for
foo and that's
all. No constructor is called, so it's
quite possible that the class will not get set up correctly. The C++
new operator not only allocates the memory, but
also calls the constructor so that the class is properly initialized.
28.3.2 The C free function
C uses the function free to return
memory to the heap. The function
free takes a single character pointer as a
parameter (thus making a lot of casting necessary):
free((char *)foo_var);
foo_var = NULL;
In C++ you delete a foo_var that points to a
simple value this way:
delete foo_var;
foo_var = NULL;
If foo_array is an pointer to an array, you delete
it with the code:
delete []foo_array;
foo_array = NULL;
Again, you must be careful when turning foo into a
class. The free function just returns the memory
to the heap. It does not call the destructor for
foo, while the delete operator
calls the destructor and then deletes the class's
memory.
C-style memory allocation is messy and risky. When converting code to
C++ you probably should get rid of all malloc,
calloc, and free calls whenever
possible.
 |
According to the ANSI C standard, memory allocated by
malloc must be deallocated by
free. Similarly, memory allocated by new must be deallocated by delete. However, most of the compilers
I've seen implement new as a call to malloc and
delete as a call to
free. In other words, mixing new/free or
malloc/free calls
will usually work. To avoid errors, you should
follow the rules and avoid mixing C and C++ operations.
|
|
|