/*
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
* You may copy, distribute, and use this software as long as this
* copyright statement is not removed.
*/
#include <stdio.h>
#include "malloc.h"
/*
* Function: realloc()
*
* Purpose: to re-allocate a data area.
*
* Arguments: cptr - pointer to area to reallocate
* size - size to change area to
*
* Returns: pointer to new area (may be same area)
*
* Narrative: verify pointer is within malloc region
* obtain mlist pointer from cptr
* verify magic number is correct
* verify inuse flag is set
* verify connection to adjoining segments is correct
* save requested size
* round-up size to appropriate boundry
* IF size is bigger than what is in this segment
* try to join next segment to this segment
* IF size is less than what is is this segment
* determine leftover amount of space
* ELSE
* allocate new segment of size bites
* IF allocation failed
* return NULL
* copy previous data to new segment
* free previous segment
* return new pointer
* split of extra space in this segment (if any)
* clear bytes beyound what they had before
* return pointer to data
*/
#ifndef lint
static
char rcs_hdr[] = "$Id: realloc.c,v 1.2 2006/07/25 10:09:48 rt Exp $";
#endif
char *
realloc(cptr,size)
char * cptr;
unsigned int size;
{
void free();
char * func = "realloc";
int i;
char * malloc();
extern int malloc_checking;
extern struct mlist * malloc_end;
extern int malloc_errno;
extern char * malloc_data_end;
extern char * malloc_data_start;
void malloc_join();
void malloc_memset();
void malloc_split();
char * memcpy();
char * new_cptr;
struct mlist * ptr;
int r_size;
/*
* IF malloc chain checking is on, go do it.
*/
if( malloc_checking )
{
(void) malloc_chain_check(1);
}
/*
* verify that cptr is within the malloc region...
*/
if( cptr < malloc_data_start || cptr > malloc_data_end )
{
malloc_errno = M_CODE_BAD_PTR;
malloc_warning(func);
return (NULL);
}
/*
* convert pointer to mlist struct pointer. To do this we must
* move the pointer backwards the correct number of bytes...
*/
ptr = (struct mlist *) (cptr - M_SIZE);
if( (ptr->flag&M_MAGIC) != M_MAGIC )
{
malloc_errno = M_CODE_BAD_MAGIC;
malloc_warning(func);
return(NULL);
}
if( ! (ptr->flag & M_INUSE) )
{
malloc_errno = M_CODE_NOT_INUSE ;
malloc_warning(func);
return(NULL);
}
if( (ptr->prev && (ptr->prev->next != ptr) ) ||
(ptr->next && (ptr->next->prev != ptr) ) ||
((ptr->next == NULL) && (ptr->prev == NULL)) )
{
malloc_errno = M_CODE_BAD_CONNECT;
malloc_warning(func);
return(NULL);
}
r_size = ++size;
M_ROUNDUP(size);
if( size > ptr->s.size )
{
malloc_join(ptr,ptr->next,1,1);
}
if( size > ptr->s.size )
{
/*
* else we can't combine it, so lets allocate a new chunk,
* copy the data and free the old chunk...
*/
new_cptr = malloc(size);
if( new_cptr == (char *) 0)
{
return(new_cptr);
}
if( r_size < ptr->r_size )
{
i = r_size;
}
else
{
i = ptr->r_size;
}
(void)memcpy(new_cptr,ptr->data,i);
free(cptr);
return(new_cptr);
} /* else... */
/*
* save amount of real data in new segment (this will be used in the
* memset later) and then save requested size of this segment.
*/
if( ptr->r_size < r_size )
{
i = ptr->r_size;
}
else
{
i = r_size;
}
ptr->r_size = r_size;
/*
* split off extra free space at end of this segment, if possible...
*/
malloc_split(ptr);
malloc_memset( ptr->data+i, M_FILL, (int) (ptr->s.size - i));
return(ptr->data);
} /* realloc(... */
syntax highlighted by Code2HTML, v. 0.9.1