Programming in C - 211-215
Programming in C - 211-215
Now we don't even have the pointer to the freed memory any more, and (as
long as we check to see that p is non-NULL before using it), we won't
misuse any memory via the pointer p.
When thinking about malloc, free, and dynamically-allocated memory in
general, remember again the distinction between a pointer and what it
points to. If you call malloc to allocate some memory, and store the pointer
which malloc gives you in a local pointer variable, what happens when the
function containing the local pointer variable returns? If the local pointer
variable has automatic duration (which is the default, unless the variable is
declared static), it will disappear when the function returns. But for the
pointer variable to disappear says nothing about the memory pointed to!
That memory still exists and, as far as malloc and free are concerned, is still
allocated. The only thing that has disappeared is the pointer variable you
had which pointed at the allocated memory. (Furthermore, if it contained the
only copy of the pointer you had, once it disappears, you'll have no way of
freeing the memory, and no way of using it, either. Using memory and
freeing memory both require that you have at least one pointer to the
memory!)
12.2.4 Reallocating Memory Blocks
Sometimes you're not sure at first how much memory you'll need. For
example, if you need to store a series of items you read from the user, and if
the only way to know how many there are is to read them until the user
types some “end'' signal, you'll have no way of knowing, as you begin
reading and storing the first few, how many you'll have seen by the time you
do see that “end'' marker. You might want to allocate room for, say, 100
items, and if the user enters a 101st item before entering the “end'' marker,
you might wish for a way to say ”uh, malloc, remember those 100 items I
asked for? Could I change my mind and have 200 instead?''
In fact, you can do exactly this, with the realloc function. You hand realloc
an old pointer (such as you received from an initial call to malloc) and a new
size, and realloc does what it can to give you a chunk of memory big
enough to hold the new size. For example, if we wanted the ip variable from
an earlier example to point at 200 ints instead of 100, we could try calling
ip = realloc(ip, 200 * sizeof(int));
nalloc = 100;
ip = (int *)malloc(nalloc * sizeof(int)); /* initial allocation */
if(ip == NULL)
{
printf("out of memory\n");
exit(1);
}
nitems = 0;
ip[nitems++] = atoi(line);
}
We use two different variables to keep track of the “array'' pointed to by ip.
nalloc is how many elements we've allocated, and nitems is how many of
them are in use. Whenever we're about to store another item in the “array,''
if nitems >= nalloc, the old “array'' is full, and it's time to call realloc to make
it bigger.
Finally, we might ask what the return type of malloc and realloc is, if they are
able to return pointers to char or pointers to int or (though we haven't seen it
yet) pointers to any other type. The answer is that both of these functions
are declared (in <stdlib.h>) as returning a type we haven't seen, void * (that
Manipal University of Jaipur Page No.: 213
Programming in C Unit 12
is, pointer to void). We haven't really seen type void, either, but what's going
on here is that void * is specially defined as a “generic'' pointer type, which
may be used (strictly speaking, assigned to or from) any pointer type.
Self Assessment Questions
1. The process of allocating memory at run time is known as
_________________.
2. malloc() function returns a pointer to integer. (True/False)
3. For deallocating memory, you can use _________ function.
4. The function that is used to alter the size of a block previously allocated
is __________________.