malloc free help

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
GLneo

malloc free help

Post 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;
???
CloudNine

Re:malloc free help

Post 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 :)
GLneo

Re:malloc free help

Post 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)
cabron

Re:malloc free help

Post 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 ...
GLneo

Re:malloc free help

Post 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
cabron

Re:malloc free help

Post by cabron »

I guess it's your free that I find a bit confusing... You're moving everything back?
GLneo

Re:malloc free help

Post by GLneo »

yes, iknow now that that is a bad idea becouse all pointers will be off but what should i do ???
cabron

Re:malloc free help

Post by cabron »

Maybe some kind of linked list?
GLneo

Re:malloc free help

Post 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 ???
AR

Re:malloc free help

Post 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.
GLneo

Re:malloc free help

Post by GLneo »

where does freelist get set to ???
AR

Re:malloc free help

Post 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.
GLneo

Re:malloc free help

Post 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
proxy

Re:malloc free help

Post 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
Post Reply