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.
13 * Purpose: to deallocate malloced data
15 * Arguments: ptr - pointer to data area to deallocate
17 * Returns: nothing of any value
20 * verify pointer is within malloc region
21 * get mlist pointer from passed address
24 * verify pointer connections with surrounding segments
26 * verify no data overrun into non-malloced area at end of segment
27 * IF possible join segment with next segment
28 * IF possible join segment with previous segment
29 * Clear all data in segment (to make sure it isn't reused)
34 char rcs_hdr
[] = "$Id: free.c,v 1.2 2006-07-25 10:07:53 rt Exp $";
43 extern int malloc_checking
;
44 extern struct mlist
* malloc_end
;
45 extern int malloc_errno
;
46 extern char * malloc_data_end
;
47 extern char * malloc_data_start
;
50 struct mlist
* oldptr
;
54 * IF malloc chain checking is on, go do it.
58 (void) malloc_chain_check(1);
62 * verify that cptr is within the malloc region...
64 if( cptr
< malloc_data_start
|| cptr
> malloc_data_end
)
66 malloc_errno
= M_CODE_BAD_PTR
;
72 * convert pointer to mlist struct pointer. To do this we must
73 * move the pointer backwards the correct number of bytes...
76 ptr
= (struct mlist
*) (cptr
- M_SIZE
);
78 if( (ptr
->flag
&M_MAGIC
) != M_MAGIC
)
80 malloc_errno
= M_CODE_BAD_MAGIC
;
85 if( ! (ptr
->flag
& M_INUSE
) )
87 malloc_errno
= M_CODE_NOT_INUSE
;
92 if( (ptr
->prev
&& (ptr
->prev
->next
!= ptr
) ) ||
93 (ptr
->next
&& (ptr
->next
->prev
!= ptr
) ) ||
94 ((ptr
->next
== NULL
) && (ptr
->prev
== NULL
)) )
96 malloc_errno
= M_CODE_BAD_CONNECT
;
101 ptr
->flag
&= ~M_INUSE
;
104 * verify that the user did not overrun the requested number of bytes.
106 for(i
=ptr
->r_size
; i
< ptr
->s
.size
; i
++)
108 if( ptr
->data
[i
] != M_FILL
)
110 malloc_errno
= M_CODE_OVERRUN
;
111 malloc_warning(func
);
116 DEBUG3(10,"pointers: prev: 0x%.7x, ptr: 0x%.7x, next: 0x%.7x",
117 ptr
->prev
, ptr
, ptr
->next
);
119 DEBUG3(10,"size: prev: %9d, ptr: %9d, next: %9d",
120 ptr
->prev
->s
.size
, ptr
->s
.size
, ptr
->next
->s
.size
);
122 DEBUG3(10,"flags: prev: 0x%.7x, ptr: 0x%.7x, next: 0x%.7x",
123 ptr
->prev
->flag
, ptr
->flag
, ptr
->next
->flag
);
126 * check to see if this block can be combined with the next and/or
127 * previous block. Since it may be joined with the previous block
128 * we will save a pointer to the previous block and test to verify
129 * if it is joined (it's next ptr will no longer point to ptr).
131 malloc_join(ptr
,ptr
->next
,0,0);
135 malloc_join(ptr
->prev
, ptr
,0,0);
137 if( oldptr
->next
!= ptr
)
139 DEBUG0(10,"Oldptr was changed");
144 * fill this block with '\02's to ensure that nobody is using a
145 * pointer to already freed data...
147 malloc_memset(ptr
->data
,M_FREE_FILL
,(int)ptr
->s
.size
);