2 * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
3 * You may copy, distribute, and use this software as long as this
4 * copyright statement is not removed.
12 * Purpose: to re-allocate a data area.
14 * Arguments: cptr - pointer to area to reallocate
15 * size - size to change area to
17 * Returns: pointer to new area (may be same area)
19 * Narrative: verify pointer is within malloc region
20 * obtain mlist pointer from cptr
21 * verify magic number is correct
22 * verify inuse flag is set
23 * verify connection to adjoining segments is correct
25 * round-up size to appropriate boundry
26 * IF size is bigger than what is in this segment
27 * try to join next segment to this segment
28 * IF size is less than what is is this segment
29 * determine leftover amount of space
31 * allocate new segment of size bites
32 * IF allocation failed
34 * copy previous data to new segment
35 * free previous segment
37 * split of extra space in this segment (if any)
38 * clear bytes beyound what they had before
39 * return pointer to data
43 char rcs_hdr
[] = "$Id: realloc.c,v 1.2 2006-07-25 10:09:48 rt Exp $";
52 char * func
= "realloc";
55 extern int malloc_checking
;
56 extern struct mlist
* malloc_end
;
57 extern int malloc_errno
;
58 extern char * malloc_data_end
;
59 extern char * malloc_data_start
;
69 * IF malloc chain checking is on, go do it.
73 (void) malloc_chain_check(1);
77 * verify that cptr is within the malloc region...
79 if( cptr
< malloc_data_start
|| cptr
> malloc_data_end
)
81 malloc_errno
= M_CODE_BAD_PTR
;
87 * convert pointer to mlist struct pointer. To do this we must
88 * move the pointer backwards the correct number of bytes...
91 ptr
= (struct mlist
*) (cptr
- M_SIZE
);
93 if( (ptr
->flag
&M_MAGIC
) != M_MAGIC
)
95 malloc_errno
= M_CODE_BAD_MAGIC
;
100 if( ! (ptr
->flag
& M_INUSE
) )
102 malloc_errno
= M_CODE_NOT_INUSE
;
103 malloc_warning(func
);
107 if( (ptr
->prev
&& (ptr
->prev
->next
!= ptr
) ) ||
108 (ptr
->next
&& (ptr
->next
->prev
!= ptr
) ) ||
109 ((ptr
->next
== NULL
) && (ptr
->prev
== NULL
)) )
111 malloc_errno
= M_CODE_BAD_CONNECT
;
112 malloc_warning(func
);
120 if( size
> ptr
->s
.size
)
122 malloc_join(ptr
,ptr
->next
,1,1);
125 if( size
> ptr
->s
.size
)
128 * else we can't combine it, so lets allocate a new chunk,
129 * copy the data and free the old chunk...
131 new_cptr
= malloc(size
);
133 if( new_cptr
== (char *) 0)
138 if( r_size
< ptr
->r_size
)
146 (void)memcpy(new_cptr
,ptr
->data
,i
);
153 * save amount of real data in new segment (this will be used in the
154 * memset later) and then save requested size of this segment.
157 if( ptr
->r_size
< r_size
)
166 ptr
->r_size
= r_size
;
169 * split off extra free space at end of this segment, if possible...
174 malloc_memset( ptr
->data
+i
, M_FILL
, (int) (ptr
->s
.size
- i
));