📄 realloc.c
字号:
/****************************************************************
Reallocate memory.
Copyright 1992 Software Development Systems, Inc.
All Rights Reserved.
****************************************************************/
#include <stdlib.h>
#include <string.h>
#include "abbr.h"
#include "alloc.h"
/************************************************************************
Reallocate the area of memory pointed to by "old" changing its
size to "sz" bytes. Return the address of a memory area
containing the same initial bytes as the old memory area up
to the smaller of the old and new sizes. If the returned address
is different from "old", the old memory area is freed.
If the request cannot be satisfied zero is returned, and the old
memory area remains allocated and its contents remain the same.
realloc( 0, sz ) acts like malloc( sz )
realloc( old, 0 ) does free( old ) and returns zero.
************************************************************************/
void *realloc( register void *old, register size_t sz ) {
register void *newp = 0;
register struct hdr *p, *next, *x;
register size_t oldsz;
if ( !old ) return malloc( sz );
if ( !sz ) { free( old ); return 0; }
sz = (sz + ALIGNMASK) & ~ALIGNMASK;
DISABLE();
/****************************************************************
Get the next link so that the current size of
the memory can be determined, and so we can check if
the next chunk if available. If there is no next
link then a bad address was passed in.
****************************************************************/
p = (struct hdr*)((char*)old - sizeof(struct busy));
if ( !ISBUSY(p) ) goto ret; /* not valid busy area */
next = (struct hdr*)((char*)p->busy.nextarea-BUSY);
if ( !next || next->busy.prevarea != p ) goto ret;/* not valid busy area */
oldsz = (char *)next - (char *)old; /* does NOT include header */
if ( oldsz >= sz ) { register size_t sizeleft;
/********************************************************
Use the same memory, just reduce the size
of allocated area for "p" if necessary.
********************************************************/
resize:
sizeleft = oldsz - sz; /* free this many bytes */
if ( sizeleft > sizeof(struct hdr) ) {
x = (struct hdr*)((char*)next - sizeleft);
x->busy.nextarea = next;
x->busy.prevarea = p;
p->busy.nextarea = (struct hdr*)((char*)x+BUSY);
next->busy.prevarea = x;
_infree(x);
if ( !ISBUSY(next) ) {
/*******************************************************
Combine with immediately following free area.
*******************************************************/
_rmfree( next ); /* remove area next from free list */
x->busy.nextarea = next->busy.nextarea; /* append next to x */
next->busy.nextarea->busy.prevarea = x; }}
newp = old; }
else if ( !ISBUSY(next) && (x=next->busy.nextarea) &&
(oldsz = (char*)x - (char*)old) >= sz ) {
/****************************************************************
Next area is free and combined size is enough.
****************************************************************/
_rmfree( next ); /* append area next to p */
p->busy.nextarea = (struct hdr*)((char*)x+BUSY);
x->busy.prevarea = p;
next = x;
goto resize; }
else if ( (x=p->busy.prevarea) && !ISBUSY(x) &&
(oldsz = (char*)next - ((char*)x+sizeof(struct busy))) >= sz ) {
char *from, *to; size_t n;
/****************************************************************
Previous area is free and combined size is enough.
****************************************************************/
_rmfree( x ); /* append area p to x */
x->busy.nextarea = (struct hdr*)((char*)next+BUSY);
next->busy.prevarea = x;
from = (char*)p + sizeof(struct busy); /* copy data down from p */
to = (char*)x + sizeof(struct busy);
n = (char *)next - (char *)old;
memmove( to, from, n );
p = x;
old = (char*)p + sizeof(struct busy);
goto resize; }
else { rchar *o, *n;
/********************************************************
Need a completely different larger area.
********************************************************/
ENABLE();
if ( !(newp = malloc( sz )) ) return 0;
o = old;
n = newp;
memmove( n, o, oldsz );
free( old );
return newp; }
ret:
ENABLE();
return newp; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -