1 <!DOCTYPE HTML PUBLIC
"-//W3O//DTD W3 HTML 2.0//EN">
2 <!-- This collection of hypertext pages is Copyright 1995-7 by Steve Summit. -->
3 <!-- This material may be freely redistributed and used -->
4 <!-- but may not be republished or sold without permission. -->
7 <link rev=
"owner" href=
"mailto:scs@eskimo.com">
8 <link rev=
"made" href=
"mailto:scs@eskimo.com">
9 <title>11.3 Reallocating Memory Blocks
</title>
10 <link href=
"sx11b.html" rev=precedes
>
11 <link href=
"sx11d.html" rel=precedes
>
12 <link href=
"sx11.html" rev=subdocument
>
15 <H2>11.3 Reallocating Memory Blocks
</H2>
17 <p>Sometimes you're not sure at first how much memory you'll need.
19 if you need to store a series of items you read from the user,
20 and if the only way to know how many there are
21 is to read them until the user types some ``end'' signal,
22 you'll have no way of knowing,
23 as you begin reading and storing the first few,
24 how many you'll have seen
25 by the time you do see that ``end'' marker.
26 You might want to allocate room for, say,
100 items,
27 and if the user enters a
101st item
28 before entering the ``end'' marker,
29 you might wish for a way to say
30 ``uh,
<TT>malloc
</TT>, remember those
100 items I asked for?
31 Could I change my mind and have
200 instead?''
32 </p><p>In fact, you can do exactly this,
33 with the
<TT>realloc
</TT> function.
34 You hand
<TT>realloc
</TT> an old pointer
35 (such as you received from an initial call to
<TT>malloc
</TT>)
37 and
<TT>realloc
</TT> does what it can
38 to give you a chunk of memory big enough
41 if we wanted the
<TT>ip
</TT> variable from an earlier example
42 to point at
200 <TT>ints
</TT> instead of
100,
45 ip = realloc(ip,
200 * sizeof(int));
47 Since you always want each block of dynamically-allocated memory
49 (so that you can treat it as if it were an array),
50 you and
<TT>realloc
</TT> have to worry about the case
51 where
<TT>realloc
</TT> can't make the old block of memory bigger
53 but rather has to relocate it elsewhere
54 in order to find enough contiguous space for the new requested size.
56 <TT>realloc
</TT> does this by returning a new pointer.
57 If
<TT>realloc
</TT> was able to make the old block of memory bigger,
58 it returns the same pointer.
59 If
<TT>realloc
</TT> has to go elsewhere to get enough contiguous memory,
60 it returns a pointer to the new memory,
61 after copying your old data there.
62 (In this case, after it makes the copy, it frees the old block.)
63 Finally, if
<TT>realloc
</TT> can't find enough memory
64 to satisfy the new request at all,
65 it returns a null pointer.
67 you usually don't want to overwrite your old pointer
68 with
<TT>realloc
</TT>'s return value
69 until you've tested it to make sure it's not a null pointer.
70 You might use code like this:
73 newp = realloc(ip,
200 * sizeof(int));
77 printf(
"out of memory\n");
79 /* but ip still points at
100 ints */
82 If
<TT>realloc
</TT> returns something other than a null pointer,
83 it succeeded, and we set
<TT>ip
</TT> to what it returned.
84 (We've either set
<TT>ip
</TT> to what it used to be or to a new pointer,
86 it points to where our data is now.)
87 If
<TT>realloc
</TT> returns a null pointer, however,
88 we hang on to our old pointer in
<TT>ip
</TT>
89 which still points at our
94 </p><p>Putting this all together,
95 here is a piece of code which reads lines of text from the user,
96 treats each line as an integer by calling
<TT>atoi
</TT>,
97 and stores each integer in a dynamically-allocated ``array'':
106 ip = malloc(nalloc * sizeof(int)); /* initial allocation */
109 printf(
"out of memory\n");
115 while(getline(line, MAXLINE) != EOF)
117 if(nitems
>= nalloc)
118 { /* increase allocation */
121 newp = realloc(ip, nalloc * sizeof(int));
124 printf(
"out of memory\n");
130 ip[nitems++] = atoi(line);
133 We use two different variables
134 to keep track of the ``array'' pointed to by
<TT>ip
</TT>.
135 <TT>nalloc
</TT> is how many elements we've allocated,
136 and
<TT>nitems
</TT> is how many of them are in use.
137 Whenever we're about to store another item in the ``array,''
138 if
<TT>nitems
>= nalloc
</TT>,
139 the old ``array'' is full,
140 and it's time to call
<TT>realloc
</TT> to make it bigger.
141 </p><p>Finally, we might ask what the return type
142 of
<TT>malloc
</TT> and
<TT>realloc
</TT> is,
143 if they are able to return
144 pointers to
<TT>char
</TT> or pointers to
<TT>int
</TT>
146 (though we haven't seen it yet)
147 pointers to any other type.
148 The answer is that both of these functions are declared
149 (in
<TT><stdlib.h
></TT>)
150 as returning a type we haven't seen,
<TT>void *
</TT>
151 (that is, pointer to
<TT>void
</TT>).
152 We haven't really seen type
<TT>void
</TT>, either,
153 but what's going on here is that
<TT>void *
</TT>
154 is specially defined as a ``generic'' pointer type,
156 (strictly speaking, assigned to or from) any pointer type.
160 <a href=
"sx11b.html" rev=precedes
>prev
</a>
161 <a href=
"sx11d.html" rel=precedes
>next
</a>
162 <a href=
"sx11.html" rev=subdocument
>up
</a>
163 <a href=
"top.html">top
</a>
166 This page by
<a href=
"http://www.eskimo.com/~scs/">Steve Summit
</a>
167 //
<a href=
"copyright.html">Copyright
</a> 1995-
1997
168 //
<a href=
"mailto:scs@eskimo.com">mail feedback
</a>