C++ : Freestore management


PART 8


Q32: Does `delete ptr' delete the ptr or the pointed-to-data?
A: The pointed-to-data.

When you read `delete p', say to yourself `delete the thing pointed to by p'.
One could argue that the keyword is misleading, but the same abuse of English
occurs when `free'ing the memory pointed to by a ptr in C:
	free(ptr);	/* why not `free_the_stuff_pointed_to_by(p)' ?? */



Q33: Can I free() ptrs alloc'd with `new' or `delete' ptrs alloc'd w/ malloc()?
A: No.  You should not mix C and C++ heap management.



Q34: Why should I use `new' instead of trustworthy old malloc()?
A: malloc() doesn't call constructors, and free() doesn't call destructors.
Besides, malloc() isn't type safe, since it returns a `void*' rather than a ptr
of the right type (ANSI-C punches a hole in its typing system to make it
possible to use malloc() without pointer casting the return value, but C++
closes that hole).  Besides, `new' is an operator that can be overridden by a
class, while `malloc' is not overridable on a per-class basis (ie: even if the
class doesn't have a constructor, allocating via malloc might do inappropriate
things if the freestore operations have been overridden).



Q35: Why doesn't C++ have a `realloc()' along with `new' and `delete'?
A: Because realloc() does *bitwise* copies (when it has to copy), which will
tear most C++ objects to shreds.  C++ objects know how to copy themselves.
They use their own copy constructor or assignment operator (depending on
whether we're copying into a previously unused space [copy-ctor] or a previous
object [assignment op]).

Moral: never use realloc() on objects of a class.  Let the class copy its own
objects.



Q36: How do I allocate / unallocate an array of things?
A: Use new[] and delete[]:

	Thing* p = new Thing[100];
	//...
	delete [] p;	//older compilers require you to use `delete [100] p'

Any time you allocate an array of things (ie: any time you use the `[...]' in
the `new' expression) you *!*MUST*!* use the `[]' in the `delete' statement.

The fact that there is no syntactic difference between a ptr to a thing and a
ptr to an array of things is an artifact we inherited from C.



Q37: What if I forget the `[]' when `delete'ing array allocated via `new X[n]'?
A: Life as we know it suddenly comes to a catastrophic end.

It is the programmer's --not the compiler's-- responsibility to get the
connection between new[] and delete[] correct.  If you get it wrong, neither a
compile-time nor a run-time error message will be generated by the compiler.

Depending on the implementation, the results *may* be harmless if the class
whose objects are being `delete'd has no destructor, but this is implementation
dependent.  If the class *does* have a destructor, only the first object in the
array (the one at `ptr[0]') will be destructed properly; the rest will simply
be abandoned.  If the destructor releases memory, this will be a memory leak;
if it closes files or unlocks semaphores or other environmental actions, system
integrity may be fractured.



Q38: What's the best way to create a `#define macro' for `NULL' in C++?
A: The best way is: don't do it.

The most portable way to compare against the nil ptr is to compare against `0'.
Some programmers use a #define to set NULL to `0', but that can conflict with
the way the standard libraries #define NULL.  There is no portable way to
define a `const' ptr called `NULL' that can be compared against any arbitrary
ptr -- the literal `0' is acceptable for this however.