* better
[mascara-docs.git] / lang / C / the.ansi.c.programming.language / c.programming.notes / sx11c.html
bloba874c067b3f4e447c9b34439ff57e12249449fbc
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. -->
5 <html>
6 <head>
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>
13 </head>
14 <body>
15 <H2>11.3 Reallocating Memory Blocks</H2>
17 <p>Sometimes you're not sure at first how much memory you'll need.
18 For example,
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>)
36 and a new size,
37 and <TT>realloc</TT> does what it can
38 to give you a chunk of memory big enough
39 to hold the new size.
40 For example,
41 if we wanted the <TT>ip</TT> variable from an earlier example
42 to point at 200 <TT>ints</TT> instead of 100,
43 we could try calling
44 <pre>
45 ip = realloc(ip, 200 * sizeof(int));
46 </pre>
47 Since you always want each block of dynamically-allocated memory
48 to be contiguous
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
52 ``in place,''
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.
66 Therefore,
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:
71 <pre>
72 int *newp;
73 newp = realloc(ip, 200 * sizeof(int));
74 if(newp != NULL)
75 ip = newp;
76 else {
77 printf("out of memory\n");
78 /* exit or return */
79 /* but ip still points at 100 ints */
81 </pre>
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,
85 but in either case,
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
90 original
91 100 values.
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'':
98 <pre>
99 #define MAXLINE 100
101 char line[MAXLINE];
102 int *ip;
103 int nalloc, nitems;
105 nalloc = 100;
106 ip = malloc(nalloc * sizeof(int)); /* initial allocation */
107 if(ip == NULL)
109 printf("out of memory\n");
110 exit(1);
113 nitems = 0;
115 while(getline(line, MAXLINE) != EOF)
117 if(nitems &gt;= nalloc)
118 { /* increase allocation */
119 int *newp;
120 nalloc += 100;
121 newp = realloc(ip, nalloc * sizeof(int));
122 if(newp == NULL)
124 printf("out of memory\n");
125 exit(1);
127 ip = newp;
130 ip[nitems++] = atoi(line);
132 </pre>
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 &gt;= 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>&lt;stdlib.h&gt;</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,
155 which may be used
156 (strictly speaking, assigned to or from) any pointer type.
157 </p><hr>
159 Read sequentially:
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>
164 </p>
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>
169 </p>
170 </body>
171 </html>