Page 1 of 1

malloc free help

Posted: Wed Jun 01, 2005 10:11 am
by GLneo
hello all, i've made the simplest mm i could but im geting converting errors like from void to char... the code is:

Code: Select all

unsigned char *heap, *max_heap;
void *malloc(unsigned size)
{
    void *ptr = heap;
    size += 4;
    if(heap + size > max_heap)
    {
        puts("    No memory left :P\n");
      return NULL;
    }   
    heap += size;
    *ptr = size;
    ptr += (unsigned char *)4;
   return ptr;
}

void free(void *mem)
{
    int size = *(mem - 4);
    memcpy((mem - 4), ((mem - 4) + size), (heap - ((mem - 4) + size)));
    heap -= size;
}
it probably has something to do with

Code: Select all

ptr += (unsigned char *)4;
???

Re:malloc free help

Posted: Wed Jun 01, 2005 10:46 am
by CloudNine
Correct. You can't do pointer arithmetic on void pointers, because in C/C++, the size of what the pointer is pointing to is crucial. For example:

Code: Select all

a+=2; //a is a char pointer
will be different to..

Code: Select all

a+=2; //a is a short pointer
In the second example, the pointer will be incremented by 4 bytes, i.e. 2*sizeof(short), whereas in the first example it would only be incremented by 2 bytes (2*sizeof(char)). You'll get it eventually :)

Re:malloc free help

Posted: Wed Jun 01, 2005 12:01 pm
by GLneo
ok, heres what im tring to do; at 4 bytes before a void pointer named "mem" is an int value whitch i want in a int veriable called "size":

Code: Select all

int size = (int)*((char)mem - 4);
8)

Re:malloc free help

Posted: Wed Jun 01, 2005 12:50 pm
by cabron
GLneo wrote: ok, heres what im tring to do; at 4 bytes before a void pointer named "mem" is an int value whitch i want in a int veriable called "size":
You can do this:

Code: Select all

     int size = ((int*)mem)[-1];
Although I hardly see how this is a working malloc ...

Re:malloc free help

Posted: Wed Jun 01, 2005 1:58 pm
by GLneo
THX, that worked

P.S. my allocator works by advancing a pointer(heap) to free memory by size needed to be allocated until it passes the size of free memory(max_heap) ;)
and what i did is one int before the pointer i stored the size of memory allocatad so in free i could look back and get the size to free

Re:malloc free help

Posted: Wed Jun 01, 2005 2:08 pm
by cabron
I guess it's your free that I find a bit confusing... You're moving everything back?

Re:malloc free help

Posted: Wed Jun 01, 2005 2:18 pm
by GLneo
yes, iknow now that that is a bad idea becouse all pointers will be off but what should i do ???

Re:malloc free help

Posted: Wed Jun 01, 2005 2:23 pm
by cabron
Maybe some kind of linked list?

Re:malloc free help

Posted: Wed Jun 01, 2005 2:53 pm
by GLneo
well incase someone hasn't notest i'm using the mm on:
http://www.osdev.org/osfaq2/index.php/A ... g%20Memory
so my new free looks like:

Code: Select all

void free(void *mem)
{
    int size = ((int*)mem)[-1];
    free_spot_data temp;
    temp.nextfree = NULL;
    temp.prevfree = NULL;
    temp.size = size;
    (free_spot_data)*((int*)mem[-1]) = temp;
}
where i go from here i dont know ???

Re:malloc free help

Posted: Wed Jun 01, 2005 11:27 pm
by AR
If you want a quick and dirty allocator that is simple then you can use a First Fit algorithm with a linked list:

Code: Select all

struct HeapHeader
{
     unsigned int Signature;
     struct HeapHeader *NextFree;
     size_t size;
};
#define HEAPSIG    0xB0E0E0F0
byte_t *HeapCurEnd, *HeapMax;
HeapHeader *FreeList;

void InitaliseHeap()
{
    extern byte_t __bssend__;
    HeapCurEnd = &__bssend__;
    HeapMax = HeapCurEnd + 0x1000000;
}

void *malloc(size_t sz)
{
    if(!sz) return NULL;
    --sz;

    /* First Fit, very wasteful (malloc(1), firstfree = 1MB, all unused space is wasted) */
    HeapHeader *Current = FreeList;
    HeapHeader *Previous = FreeList;
    while(Current)
    {
        if(Current->size > sz)
        {
              /* Pull out of FreeList and return it */
              Previous->NextFree = Current->NextFree;
              if(Current == FreeList) FreeList = Current->NextFree;
              Current->NextFree = NULL;
              return (void*) ++Current;
        }
        Previous = Current;
        Current = Current->NextFree;
    }

    /* No free entries, see if we can create one */
    ++sz;
    if(HeapCurEnd + sz + sizeof(HeapHeader) > HeapMax)
         return NULL;

    /* Create a new block */
    Current = (HeapHeader*)HeapCurEnd;
    Current->Signature = HEAPSIG;
    Current->size = sz;
    Current->NextFree = NULL;

    /* Modify the heap pointer and return */
    HeapCurEnd += sz + sizeof(HeapHeader);
    return (void*) ++Current;
}

void free(void *ptr)
{
    HeapHeader *hh = (HeapHeader*)ptr;
    --hh;

    /* Check signature */
    if(hh->Signature != HEAPSIG)
         return;

    /* Insert into FreeList */
    if(FreeList == NULL)
         FreeList = hh;
    else
    {
         hh->NextFree = FreeList->NextFree;
         FreeList->NextFree = hh;
    }
}
Note that I just made this up as I went, it should work but is untested and there might be syntax errors. This code is intended as educational, you'll be better off in the long run if you just examine how it works rather than copying it.

Re:malloc free help

Posted: Thu Jun 02, 2005 12:10 pm
by GLneo
where does freelist get set to ???

Re:malloc free help

Posted: Fri Jun 03, 2005 12:13 am
by AR
Sounds like you need more practice with the language itself as well as how the linker generates executables. You may want to copy the code into a color coded editor to make if more legible.

FreeList starts out as NULL, it becomes valid when something is freed. The while(Current) at the start of the malloc will be completely skipped if FreeList isn't set.

Re:malloc free help

Posted: Fri Jun 03, 2005 1:30 pm
by GLneo
but if you diclare something doesn't it get set to random, where do you intalize it. ???

but anyway i set it to null made small changes and it works fine, much thx. ;) ;D

Re:malloc free help

Posted: Fri Jun 03, 2005 3:06 pm
by proxy
uninitialized globals will go into the bss section which should be zeroed. I suppose if you haven't implemented zeroing of the bss section of your kernel it will be random. However, if you do properly zero out the bss section on load, unitialized globals will in fact be zeroed.

proxy