Malloc in Turbo C

Derek R. Foster dfoster at jarthur.Claremont.EDU
Wed Feb 28 07:19:59 AEST 1990


In article <26316 at qfagus.OZ> gordon at qfagus.OZ (Peter Gordon) writes:
>
>Please tell me I'm doing something stupid.  The following code works on
>Microsoft C and a MIPS/1000 runnung UNIX Sys V Release 4_0.
>On Turbo C  (ver 2) it crashes after a variable number of frees.  I've tried
>------------------- cut here ------------------------------
>X	char **head, **cp;
>X	int	i;
>X	head = (char **)malloc(200 * sizeof(char **));

Wait a minute. How can you have a pointer to a pointer to char aimed at an
array of two hundred pointers to pointers to char? This is a type clash.
If it is a pointer to a pointer to char, it should point (surprisingly
enough) to one, or a block of, pointers to char.
shouldn't it be
   head = (char **) malloc(200 * sizeof(char *));
or if the array IS supposed to be of char **'s, 
  char ***head, ***cp;
  head = (char ***) malloc(200 * sizeof(char **));
?

>X	for(cp = head, i = 0; i < 200; ++i, ++cp)
>X	{
>X		fprintf(stdout,"Freeing %d\n", i);
>X		fflush(stdout);
>X		free(cp);
>X	}

Think about what you're doing. You've created ONE array of 200 pointers to
char pointers,
and assigned head to point to the address of it. Then you (200 times)
try to free what cp points to (it starts out as head), then increment
cp. The first time it goes through the loop, it frees your ENTIRE array of
pointers. Every other time, you're not passing 'free' the address of
the start of a malloc'ed block of memory. Instead, you're giving it
a pointer into the MIDDLE of a block of memory (which has already been
freed anyway). If you've only malloc'ed one thing, why are you
trying to free more than one thing? Mallocs and frees should be on a
one-to-one correspondance. Also, you should never pass an address to
'free' that wasn't returned DIRECTLY, WITHOUT BEING INCREMENTED OR
MODIFIED IN ANY WAY, by malloc (or some other allocation routine).
Remember, when you 'malloc' a block of memory, the computer considers
it ONE BLOCK. You can't dispose of it piecemeal (other than with
realloc, etc.)

I think I may see what you are trying to do here. I may be wrong, but
I would guess that head is supposed to point to an array of pointers
(should these be char pointers instead of pointers to char pointers?)
and that those pointers point to other chunks of
memory which are what you are really trying to free. (for instance, a
dynamically allocated array of strings).

If this is the case, you are attempting to free WHAT EACH OF THOSE
POINTERS POINTS TO. Ignoring the fact that the above program never
assigns any memory for those pointers to point to (in fact, does
not initialize them at all), there is another mistake in it.
You are trying to free the memory that cp points to, when in fact what
you want to do is free the memory that what cp POINTS TO points to. In
other words, instead of free(cp), use free(*cp).
Of course, after you've done all that, your original array of pointers
will still have to be freed (via free(head)).

Of course, I could be completely wrong about the intent of this code.
If, in fact, all you are really trying to do is deallocate the space
assigned to your array of head, just free(head). No loop is necessary.

Hope this helps!

Derek Riippa Foster



More information about the Comp.lang.c mailing list