]> andersk Git - splint.git/blob - doc/html/realloc.htm
Added web version of the realloc document.
[splint.git] / doc / html / realloc.htm
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">\r
2 \r
3 <html>\r
4 <head>\r
5     <title>Using Wrapper Functions</title>\r
6 </head>\r
7 \r
8 <body>\r
9     <div class="Section1">\r
10         <h1>Using Wrapper Functions</h1>\r
11 \r
12         <p>The propose of this document is to provide an example of\r
13         how to use wrapper functions to create programs that are\r
14         more robust and that Splint can check more\r
15         effectively.&nbsp; The C standard library function realloc\r
16         has complex semantics and is easy to use incorrectly.&nbsp;\r
17         Still, it is a popular function, and we are frequently\r
18         asked how to use Splint to check code that uses\r
19         realloc.&nbsp; We hope to answer these questions in this\r
20         section.&nbsp; Additionally, we hope this example will\r
21         provide insight into other ways to work around some of the\r
22         limitations of Splint&rsquo;s checking, and serve as a\r
23         template for users wishing to create their own wrapper\r
24         functions.</p>\r
25 \r
26         <p>Splint cannot currently describe general functions where\r
27         some of the attributes are dependent on one or more of the\r
28         possible return values.&nbsp; Often, functions are defined\r
29         to modify their outputs, and perhaps allocate storage, but\r
30         can also return an error indication, in which case none of\r
31         the modifications or allocations will take place.</p>\r
32 \r
33         <p>One very common example of this is the C standard\r
34         library function realloc( void *pointer, size_t\r
35         size).&nbsp; When realloc succeeds, the pointer passed to\r
36         it is no longer valid.&nbsp; The returned pointer points to\r
37         available storage with the specified size, and the values\r
38         are copied from the leading portion of the original storage\r
39         indicated by the pointer passed to the function.&nbsp; When\r
40         realloc returns a NULL pointer, and more than zero bytes\r
41         were supposed to be allocated, no new storage has been\r
42         allocated.&nbsp; The original pointer passed in is not\r
43         deallocated and its contents are still accessible.&nbsp;\r
44         (Under ANSI C '89 and later, malloc and realloc may return\r
45         NULL if asked for zero bytes.&nbsp; In this case, realloc\r
46         would release the old storage.)</p>\r
47 \r
48         <p>If you use realloc, -usereleased can be used to suppress\r
49         warnings.&nbsp; However, this may result in legitimate\r
50         warnings for other errors being suppressed as well.&nbsp;\r
51         If you don't mind crafting your code to work around\r
52         Splint's quirks, you can isolate this difficult-to-describe\r
53         behavior to a single function that's easy to verify by\r
54         inspection, and use that function elsewhere.&nbsp; For\r
55         example:</p>\r
56 \r
57         &nbsp;&nbsp;&nbsp; /*@-usereleased@*/<br>\r
58 \r
59         &nbsp;&nbsp;&nbsp; static /*@null@*/ void *<br>\r
60 \r
61         &nbsp;&nbsp;&nbsp; grow_or_free (/*@only@*/ void *ptr,\r
62         size_t newsize)<br>\r
63 \r
64         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\r
65         /*@*/<br>\r
66 \r
67         &nbsp;&nbsp;&nbsp; {<br>\r
68 \r
69         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void\r
70         *newptr;<br>\r
71 \r
72         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newptr =\r
73         realloc (ptr, newsize);<br>\r
74 \r
75         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (newptr ==\r
76         NULL &amp;&amp; newsize != 0) {<br>\r
77 \r
78         \r
79         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\r
80         /* Splint would complain,<br>\r
81 \r
82         \r
83         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\r
84         but this is correct.&nbsp; */<br>\r
85 \r
86         \r
87         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\r
88         free (ptr);<br>\r
89 \r
90         \r
91         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\r
92         return NULL;<br>\r
93 \r
94         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>\r
95 \r
96         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return\r
97         newptr;<br>\r
98 \r
99         &nbsp;&nbsp;&nbsp; }<br>\r
100 \r
101         &nbsp;&nbsp;&nbsp; /*@=usereleased@*/<br>\r
102 \r
103         <p>It would also be possible to use a function that always\r
104         returns a valid pointer, and separately indicates whether\r
105         it managed to change the size to that desired by the\r
106         caller.</p>\r
107     </div>\r
108 </body>\r
109 </html>\r
This page took 0.046996 seconds and 5 git commands to generate.