gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > Malloc fails

#170632 - Azenris - Thu Oct 08, 2009 7:40 pm

Hi, just wondering if anyone knows why :/

I have the code below which just basically loads a sprite at a point in the level.

Code:
// =================================================================================
// _LoadSprite:
// @ cursor:   position to load the sprite
// @ spriteID:    id of the sprite
void CLevelManager::_LoadSprite(u16 cursor, u16 spriteID)
{
   if (spriteID != 0)                                             // ensure it isnt a blank id
   {
      CMobile *pMobile = NULL;                                    // pointer to a mobile
      location loc(cursor, LEVEL_TILES_X, LEVEL_TILES_Y);                  // change a mappoint into x, y values
      
      switch (_GetSpriteType(spriteID))
      {
      // this sprite is not specified, it will be further checked to
      // see if it is in anyway special or not
      case SPRITE_TYPE_UNDEF:

         if (IS_ITEM_CHERRY(spriteID))
            ++m_cherriesOnScreen;

         pMobile = new MEMORY_LEVEL CObject(this, spriteID, 1, loc, false);
         m_mobiles.push_back(pMobile);
         break;

      // the sprite is required to load offscreen
      case SPRITE_TYPE_OFFSCREEN:
         pMobile = new MEMORY_LEVEL CObject(this, spriteID, 1, loc, false);
         pMobile->MakeInvisible();
         m_mobiles.push_back(pMobile);
         break;

      // the sprite is an enemy
      case SPRITE_TYPE_ENEMY:
         pMobile = new MEMORY_LEVEL CEnemy(this, spriteID, 10, loc, false);
         m_mobiles.push_back(pMobile);
         ++m_enemiesOnScreen;
         break;

      // the sprite is an enemy NYI
      case SPRITE_TYPE_BOSS:
         ++m_bossesOnScreen;
         break;

      // the sprite is the player
      case SPRITE_TYPE_PLAYER:
         m_startingPoint = loc;
         m_pPlayer = new MEMORY_LEVEL CPlayer(this, spriteID, STARTING_HEALTH, loc);
         m_mobiles.push_back(m_pPlayer);
         break;

      default:
         DEBUG_HALT("LVL:_LoadSprite - Unidentified Mobile");
         break;
      }

      if (m_mobiles.size() == MAX_MOBILES)
         DEBUG_HALT("LVL:_LoadSprite - Mobile Overflow");
   }
}


below is my new/delete

Code:
// =================================================================================
// OPERATOR: new
void *operator new(size_t size)
{
#ifndef _RELEASE_BUILD
   g_objectCount += 1;
   g_memorySize += size;
   size_t memNeeded = size + sizeof(DataHeader);
   g_memoryHeaderSize += sizeof(DataHeader);
   char *pMemory = (char*)malloc(memNeeded);
   
   if (pMemory == NULL)
   {
      PREP_TEST_PRINT
         printf("\n MEMORY FAILURE\n\n mem header:--%d\n mem data:----%d\n mem total:---%d\n mem objects:-%d\n",
            GetTotalHeaderMemorySize(), GetTotalMemorySize(), GetTotalHeaderMemorySize() + GetTotalMemorySize(), GetObjectCount());
      printf("\n ATTEMPTED ALLOCATION\n\n data size:--------%d\n header size:------%d\n total mem needed:-%d", size, sizeof(DataHeader), size + sizeof(DataHeader));
      while(1){}
   }

   DataHeader *pHeader = (DataHeader*)pMemory;
   pHeader->dataSize = size;
   void *pStart = pMemory + sizeof(DataHeader);
   return pStart;
#else
   return malloc(size);
#endif
}

// =================================================================================
// OPERATOR: delete
void operator delete(void *pData)
{
#ifndef _RELEASE_BUILD
   g_objectCount -= 1;
   DataHeader *pHeader = (DataHeader*)((char*)pData - sizeof(DataHeader));
   g_memorySize -= pHeader->dataSize;
   g_memoryHeaderSize -= sizeof(DataHeader);
   free(pHeader);
#else
   free(pData);
#endif
}


When I run my program I get a a failure outputting:
Code:

=============================
=
= MEMORY FAILURE
=
= mem header:--64
= mem data:----28239
= mem total:---28303
= mem objects:-16
=
= ATTEMPTED ALLOCATION
=
= data size:--------52
= header size:------4
= total mem needed:-56
=============================


the failed new is the first mobile of the level, the player. This is the failing call
Code:
m_pPlayer = new MEMORY_LEVEL CPlayer(this, spriteID, STARTING_HEALTH, loc);


Am I out of memory or something? What should I do :/


Ty for any help
_________________
My Homebrew Games

#170650 - Azenris - Fri Oct 09, 2009 3:13 pm

Hmm, might be onto something. Just gonna test sommet! Sorry for post

EDIT:

I checked a previous allocation, it was big and included an array of u16, 2000 elements. I changed that to a pointer and dynamically allocated that.

Is it because I tried to allocate something to big at once? or because the array was to big.

Well anyway it works now, thought id post how I changed it to work incase anyone else has the same problem
_________________
My Homebrew Games

#170652 - sverx - Fri Oct 09, 2009 3:35 pm

Azenris wrote:
I checked a previous allocation, it was big and included an array of u16, 2000 elements.


that's barely 4KB...

#170671 - Azenris - Sat Oct 10, 2009 2:43 pm

ok I made a stupid question :( Its just that it was my biggest allocation. but anyway I was re-looking at some of my code and I found a loop which was writing past the end of an array. This was probably my real problem.
_________________
My Homebrew Games

#170672 - keldon - Sat Oct 10, 2009 7:13 pm

Azenris wrote:
ok I made a stupid question :( Its just that it was my biggest allocation. but anyway I was re-looking at some of my code and I found a loop which was writing past the end of an array. This was probably my real problem.


Arrays are evil!

Ok, I use them very often; but just be aware of the evil you are doing ;)

#170921 - Azenris - Mon Oct 26, 2009 5:00 pm

OK I got a problem recently with weird behaviour, and I bet its an array causing the problem!

I just made an enemy spawner, and it crashes on making its third enemy, but if my character collects an item it wont, also if my level has more items on to start with the problem doesn't show. blah.

I'm going to start using more of the containers cos its annoying me!

EDIT:
Well I found my bad code and fixed it. It was actually some older code too, meaning it was hiding the whole time and only just became a noticeable problem :/
_________________
My Homebrew Games

#170930 - keldon - Tue Oct 27, 2009 12:20 am

Was it a bug that could have been caught with an assertion? Arrays are fine when used properly; just be sure that all variables/pointers are initialized before they are accessed and the state accepts your command (be it array index, or function).

Be sure to use sparingly; there is no need to (for example) assert something that has already been proved true already.

#170950 - Azenris - Tue Oct 27, 2009 4:15 pm

I actually caught the bug with an assert, I didn't have many in my code, but went through it adding them and caught it.
_________________
My Homebrew Games