realloc.c 2.93 KB
/*
=============================================================================
        Copyright (C) 1997-1999 NINTENDO Co.,Ltd.
        
        $RCSfile: realloc.c,v $
        $Revision: 1.1.1.1 $
        $Date: 2002/10/30 02:07:09 $
=============================================================================
関数名:realloc
-----------------------------------------------------------------------------
書式:  #include <malloc.h>
        void *realloc(void *ptr, int size);
引数:  ptr 確保している領域の先頭ポインタ
        size 変更するサイズ。
戻り値:再割り当てして確保した領域の先頭ポインタ。
        確保に失敗したら NULL を返す。
説明:  InitHeap で確保した領域に確保したメモリブロックのサイズを
        size 以上に変更する。
-----------------------------------------------------------------------------
*/
#include    <ultra64.h>
#include    "string.h"
#include    "malloc.h"
#include    "_malloc.h"

void *realloc(void *ptr, int size)
{
    unsigned int    *next2;
    unsigned int    size2;
    unsigned char   *p2;
    struct  mallocST  *malloc_st_ptr ;

    if( (int)malloc_ptr == -1 ){
	return  NULL;
    }

    if( !ptr ){
	return _malloc( malloc_ptr, size ); /*  新規にメモリ確保 */
    }

    if( !size ){ /* 現在のメモリを開放 */
        _free(malloc_ptr, ptr);
        return  NULL;
    }

    size += 15;
    size &= (~15);

    p2 = (unsigned char *)ptr - MALLOC_HEADSIZE;
    malloc_st_ptr = (struct mallocST *)p2;

    if( !malloc_st_ptr->flag ){
	return NULL;
    }

    next2 = malloc_st_ptr->next;
    size2 = malloc_st_ptr->size;

    malloc_st_ptr = (struct mallocST *)next2;
    if (next2 && !malloc_st_ptr->flag)  {
        size2 += malloc_st_ptr->size + MALLOC_HEADSIZE;
        next2 = (unsigned int *)malloc_st_ptr->next;
    }

    malloc_st_ptr = (struct mallocST *)p2;
    if( size > size2 ){
        /*  現在のポインタの位置からでは指定サイズ確保が出来ない。 */
        p2 = (unsigned char *)_malloc(malloc_ptr, size);
        if( p2 == NULL ){
	    return  NULL;
	}
        _nmemcpy(p2, ptr, size);
        _free(malloc_ptr, ptr);
        return  p2;
    }else{
        /*  今のポインタを継承したままサイズを変更する。*/
        if( (size + MALLOC_HEADSIZE + 16) < size2 ){
	    /* ブロックを再分割する必要がある場合 */
	    /*
            malloc_st_ptr->next
	      = (unsigned int *)((unsigned int)ptr + size + MALLOC_HEADSIZE);
	      */
            malloc_st_ptr->next
	      = (unsigned int *)((unsigned int)ptr + size) ;
            malloc_st_ptr->size = size;
    
            malloc_st_ptr = (struct mallocST *)malloc_st_ptr->next;
            malloc_st_ptr->next = next2;
            malloc_st_ptr->size = size2 - size - MALLOC_HEADSIZE;
            malloc_st_ptr->flag = 0;
        }else{
	    /* ブロックを再分割する必要がない場合 (ブロックのサイズが
               確保しようとしているサイズと同じ大きさだった場合) */
            malloc_st_ptr->next = next2;
            malloc_st_ptr->size = size2;
        }
        return  ptr;
    }
}