pointer arithmetic / casting problem

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
deniska
Posts: 71
Joined: Mon Oct 17, 2005 1:38 pm
Location: New York

pointer arithmetic / casting problem

Post by deniska »

While porting a game from lynux I got stock with a runtime error (blue screen of death), pointing to line 54 (marked by a comment in code) of following function:

Code: Select all

void *Z_Malloc (int size, int tag, void *user)
{
        int             extra;
        memblock_t      *start, *rover, *new, *base;
//
// scan through the block list looking for the first free block
// of sufficient size, throwing out any purgable blocks along the way
//
        size += sizeof(memblock_t);     // account for size of block header


//
// if there is a free block behind the rover, back up over them
//
        base = mainzone->rover;
        if (!base->prev->user)
                base = base->prev;

        rover = base;
        start = base->prev;

        do
        {
                if (rover == start)     // scaned all the way around the list
                        {
                        SoftError("OHSHIT\n");
                        Z_DumpHeap(0,200);
                        Error ("Z_Malloc: failed on allocation of %i bytes",size);
                        }
                if (rover->user)
                {
                        if &#40;rover->tag < PU_PURGELEVEL&#41;
                        // hit a block that can't be purged, so move base past it
                                base = rover = rover->next;
                        else
                        &#123;
                        // free the rover block &#40;adding the size to base&#41;
                                base = base->prev;      // the rover can be the base block
                                Z_Free &#40;&#40;byte *&#41;rover+sizeof&#40;memblock_t&#41;&#41;;
                                base = base->next;
                                rover = base->next;
                        &#125;
                &#125;
                else
                        rover = rover->next;
        &#125; while &#40;base->user || base->size < size&#41;;

//
// found a block big enough
//
        extra = base->size - size;
        if &#40;extra >  MINFRAGMENT&#41;
        &#123;       // there will be a free fragment after the allocated block
                new = &#40;memblock_t *&#41; &#40;&#40;byte *&#41;base + size &#41;;
                new->size = extra;          //!!!EXECUTION BREAKS HERE!!!
                new->user = NULL;               // free block
                new->tag = 0;
                new->prev = base;
                new->next = base->next;
                new->next->prev = new;
                base->next = new;
                base->size = size;
        &#125;

        if &#40;user&#41;
        &#123;
                base->user = user;                      // mark as an in use block
                *&#40;void **&#41;user = &#40;void *&#41; &#40;&#40;byte *&#41;base + sizeof&#40;memblock_t&#41;&#41;;
        &#125;
        else
        &#123;
                if &#40;tag >= PU_PURGELEVEL&#41;
                        Error &#40;"Z_Malloc&#58; an owner is required for purgable blocks"&#41;;
                base->user = &#40;void *&#41;2;         // mark as in use, but unowned
        &#125;
        base->tag = tag;

        mainzone->rover = base->next;   // next allocation will start looking here


        return &#40;void *&#41; &#40;&#40;byte *&#41;base + sizeof&#40;memblock_t&#41;&#41;;
&#125;


Code: Select all

typedef struct memblock_s
&#123;
         int     size;   // including the header and possibly tiny fragments
         void    **user; // NULL if a free block
         int     tag;    // purgelevel
         struct memblock_s   *next, *prev;
&#125; memblock_t;

typedef struct
&#123;
         int     size;          // total bytes malloced, including header
         memblock_t  blocklist; // start / end cap for linked list
         memblock_t  *rover;
&#125; memzone_t;


Does anyone know what may have gone wrong?
Same code runs fine under cygwin.

Thank you in advance
charliex
Posts: 16
Joined: Thu Jan 26, 2006 4:03 pm

Post by charliex »

is size odd ? or does new end up odd
deniska
Posts: 71
Joined: Mon Oct 17, 2005 1:38 pm
Location: New York

Post by deniska »

charliex wrote:is size odd ? or does new end up odd
Yeah,
It get's called with:
Z_Malloc ( 5, 1,..)
charliex
Posts: 16
Joined: Thu Jan 26, 2006 4:03 pm

Post by charliex »

can't use an unaligned pointer like that, the function needs to be changed to align addresses from the pool.
Post Reply