By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,972 Members | 1,126 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,972 IT Pros & Developers. It's quick & easy.

exception: std::bad_alloc

P: 2
Hello everyone,
I've been a regular of this forum but this is my first post, generally I can find the answer to my question already, but this time I'm having a somewhat specific problem.
For fun I've been working on making a 3d game (who hasn't haha) and while it's nothing special at the moment I was making some decent headway. I'm working on constructing an octree for my triangle data, but I keep getting this pesky bad_alloc runtime error. I've looked up online for more information on it, including this post here on TheScripts http://www.thescripts.com/forum/thread523575.html. Unfortunately it just reaffirmed that I'm probably doing something stupid without giving me any direction. Here is the octree class:

Header:
Expand|Select|Wrap|Line Numbers
  1. #pragma once
  2.  
  3. #include <d3dx9.h>
  4. #include <d3d9.h>
  5. #include <string>
  6. #include <vector>
  7.  
  8. #include <iostream>
  9. #include <fstream>
  10.  
  11. #pragma comment(lib, "d3dx9.lib")
  12. #pragma comment(lib, "d3d9.lib")
  13.  
  14. class czOctree
  15. {
  16.     public:
  17.         czOctree( );
  18.  
  19.         ~czOctree( ) { }
  20.  
  21.         void Release( );
  22.         void Create(D3DXVECTOR3* pVerts, int iNumVerticies);
  23.  
  24.     private:
  25.         static const int maxNodes = 3;
  26.         static const int minNumTriangles = 250;
  27.  
  28.     protected:
  29.         int numVerticies;
  30.         D3DXVECTOR3* pVerticies;
  31.         D3DXVECTOR3 center;
  32.         float diameter;
  33.         bool containsTriangles;
  34.         czOctree* oChildren[8];
  35.  
  36.         enum octreeParts { TOP_FRONT_LEFT, TOP_FRONT_RIGHT, TOP_BACK_LEFT, TOP_BACK_RIGHT,
  37.             BOTTOM_FRONT_LEFT, BOTTOM_FRONT_RIGHT, BOTTOM_BACK_LEFT, BOTTOM_BACK_RIGHT };
  38.  
  39.         inline float abs_f(float f) { if(f<0) return -f; return f; };
  40.         inline D3DXVECTOR3 GetNodeCenter(D3DXVECTOR3 currentCenter, float fDiameter, int iWhichNode);
  41.  
  42.         void SetData(D3DXVECTOR3* pVerts, int numVerts);
  43.         void SetNode(D3DXVECTOR3* pVerts, int numVerts);
  44.         void CreateNode(D3DXVECTOR3* pVerts, int numVerts, D3DXVECTOR3 vCenter, float fDiameter);
  45.         void CreateNodeEnd(D3DXVECTOR3* pTotalVerts, int NumTotalVerts, bool* pBools, D3DXVECTOR3 vCenter, float fDiameter, int iTriangles, int iWhichNode);
  46.  
  47.  
  48. };
  49.  
and the source file
Expand|Select|Wrap|Line Numbers
  1. #include "octrees.h"
  2.  
  3. const bool DEBUG = true;
  4. #define DMSGBOX( a ) { if(DEBUG) MessageBox(NULL, a, "DEBUG", 0); }
  5. #define DMSGFILE( file, a ) { if(DEBUG && f.is_open()) file << a << std::endl; }
  6. int g_currentLevel;
  7.  
  8. czOctree::czOctree( )
  9. {
  10.     numVerticies = NULL;
  11.     pVerticies = NULL;
  12.     center = D3DXVECTOR3(0,0,0);
  13.     diameter = 0.0f;
  14.     ZeroMemory(oChildren, sizeof(oChildren));
  15. }
  16.  
  17. void czOctree::SetData(D3DXVECTOR3 *pVerts, int numVerts)
  18. {
  19.     if( pVerts == NULL || numVerts == 0 )
  20.         return;
  21.  
  22.     for(int i=0; i<numVerts; i++)
  23.     {
  24.         center.x = center.x + pVerts[i].x;
  25.         center.y = center.y + pVerts[i].y;
  26.         center.z = center.z + pVerts[i].z;
  27.     }
  28.  
  29.     center.x = center.x / (float)numVerts;
  30.     center.y = center.y / (float)numVerts;
  31.     center.z = center.z / (float)numVerts;
  32.  
  33.     float widthMax = 0.0f;
  34.     float heightMax = 0.0f;
  35.     float depthMax = 0.0f;
  36.  
  37.     for(int i=0; i<numVerts; i++)
  38.     {
  39.         float width = abs_f(pVerts[i].x - center.x);
  40.         float height = abs_f(pVerts[i].y - center.y);
  41.         float depth = abs_f(pVerts[i].z - center.z);
  42.  
  43.         if( width > widthMax )        widthMax = width;
  44.         if( height > heightMax )    heightMax = height;
  45.         if( depth > depthMax )        depthMax = depth;
  46.     }
  47.  
  48.     widthMax *= 2;
  49.     heightMax *= 2;
  50.     depthMax *= 2;
  51.  
  52.     diameter = max( widthMax, max(heightMax,depthMax) );
  53. }
  54.  
  55. void czOctree::CreateNode(D3DXVECTOR3 *pVerts, int numVerts, D3DXVECTOR3 vCenter, float fDiameter)
  56. {
  57.  
  58.     center = vCenter;
  59.     int numTriangles = numVerts / 3;
  60.     diameter = fDiameter;
  61.  
  62.     if( (numTriangles < minNumTriangles) || (g_currentLevel >= maxNodes) )
  63.     {
  64.         SetNode(pVerts, numVerts);
  65.         containsTriangles = true;
  66.     }
  67.     else
  68.     {
  69.         containsTriangles = false;
  70.         bool* pBoolArray1 = new bool[numTriangles];
  71.         bool* pBoolArray2 = new bool[numTriangles];
  72.         bool* pBoolArray3 = new bool[numTriangles];
  73.         bool* pBoolArray4 = new bool[numTriangles];
  74.         bool* pBoolArray5 = new bool[numTriangles];
  75.         bool* pBoolArray6 = new bool[numTriangles];
  76.         bool* pBoolArray7 = new bool[numTriangles];
  77.         bool* pBoolArray8 = new bool[numTriangles];
  78.  
  79.         ZeroMemory(pBoolArray1, numTriangles);
  80.         ZeroMemory(pBoolArray2, numTriangles);
  81.         ZeroMemory(pBoolArray3, numTriangles);
  82.         ZeroMemory(pBoolArray4, numTriangles);
  83.         ZeroMemory(pBoolArray5, numTriangles);
  84.         ZeroMemory(pBoolArray6, numTriangles);
  85.         ZeroMemory(pBoolArray7, numTriangles);
  86.         ZeroMemory(pBoolArray8, numTriangles);
  87.  
  88.         D3DXVECTOR3 cntr = center;
  89.         for(int i=0; i< numVerts; i++)
  90.         {
  91.             D3DXVECTOR3 point = pVerts[i];
  92.             if((point.y >= cntr.y) && (point.x <= cntr.x) && (point.z >= cntr.z) )
  93.                 pBoolArray1[i/3] = true;                
  94.             if( (point.y >= cntr.y) && (point.x >= cntr.x) && (point.z >= cntr.z) )
  95.                 pBoolArray2[i/3] = true;
  96.             if( (point.y >= cntr.y) && (point.x <= cntr.x) && (point.z <= cntr.z) )
  97.                 pBoolArray3[i/3] = true;
  98.             if( (point.y >= cntr.y) && (point.x >= cntr.x) && (point.z <= cntr.z) )
  99.                 pBoolArray4[i/3] = true;
  100.             if( (point.y <= cntr.y) && (point.x <= cntr.x) && (point.z >= cntr.z) )
  101.                 pBoolArray5[i/3] = true;
  102.             if( (point.y <= cntr.y) && (point.x >= cntr.x) && (point.z >= cntr.z) )
  103.                 pBoolArray6[i/3] = true;
  104.             if( (point.y <= cntr.y) && (point.x <= cntr.x) && (point.z <= cntr.z) )
  105.                 pBoolArray7[i/3] = true;
  106.             if( (point.y <= cntr.y) && (point.x >= cntr.x) && (point.z <= cntr.z) )
  107.                 pBoolArray8[i/3] = true;
  108.  
  109.         }
  110.  
  111.         int iCount1, iCount2, iCount3, iCount4, iCount5, iCount6, iCount7, iCount8;
  112.         iCount1 = iCount2 = iCount3 = iCount4 = iCount5 = iCount6 = iCount7 = iCount8 = 0;
  113.  
  114.         for(int i=0; i<numTriangles; i++)
  115.         {
  116.             if(pBoolArray1[i]) iCount1++;
  117.             if(pBoolArray2[i]) iCount2++;
  118.             if(pBoolArray3[i]) iCount3++;
  119.             if(pBoolArray4[i]) iCount4++;
  120.             if(pBoolArray5[i]) iCount5++;
  121.             if(pBoolArray6[i]) iCount6++;
  122.             if(pBoolArray7[i]) iCount7++;
  123.             if(pBoolArray8[i]) iCount8++;
  124.         }
  125.  
  126.         CreateNodeEnd(pVerts, numVerts, pBoolArray1, cntr, fDiameter, iCount1, TOP_FRONT_LEFT );
  127.         CreateNodeEnd(pVerts, numVerts, pBoolArray2, cntr, fDiameter, iCount2, TOP_FRONT_RIGHT);
  128.         CreateNodeEnd(pVerts, numVerts, pBoolArray3, cntr, fDiameter, iCount3, TOP_BACK_LEFT);
  129.         CreateNodeEnd(pVerts, numVerts, pBoolArray4, cntr, fDiameter, iCount4, TOP_BACK_RIGHT);
  130.         CreateNodeEnd(pVerts, numVerts, pBoolArray5, cntr, fDiameter, iCount5, BOTTOM_FRONT_LEFT);
  131.         CreateNodeEnd(pVerts, numVerts, pBoolArray6, cntr, fDiameter, iCount6, BOTTOM_FRONT_RIGHT);
  132.         CreateNodeEnd(pVerts, numVerts, pBoolArray7, cntr, fDiameter, iCount7, BOTTOM_BACK_LEFT);
  133.         CreateNodeEnd(pVerts, numVerts, pBoolArray8, cntr, fDiameter, iCount8, BOTTOM_BACK_RIGHT);
  134.  
  135.         delete[] pBoolArray1;
  136.         delete[] pBoolArray2;
  137.         delete[] pBoolArray3;
  138.         delete[] pBoolArray4;
  139.         delete[] pBoolArray5;
  140.         delete[] pBoolArray6;
  141.         delete[] pBoolArray7;
  142.         delete[] pBoolArray8;
  143.     }
  144. }
  145.  
  146. void czOctree::CreateNodeEnd(D3DXVECTOR3 *pTotalVerts, int NumTotalVerts, bool *pBools, D3DXVECTOR3 vCenter, float fDiameter, int iTriangles, int iWhichNode)
  147. {
  148.     if( iTriangles = 0 )
  149.         return;
  150.  
  151.     D3DXVECTOR3* nodeVerts = new D3DXVECTOR3[iTriangles*3];
  152.     int count = 0;
  153.  
  154.     for(int i=0; i<NumTotalVerts; i++)
  155.     {
  156.         if( pBools[i/3] ) 
  157.         {
  158.             nodeVerts[count] = pTotalVerts[i];
  159.             count++;
  160.         }
  161.     }
  162.  
  163.     oChildren[iWhichNode] = new czOctree;
  164.     D3DXVECTOR3 newCenter = GetNodeCenter(vCenter, fDiameter, iWhichNode);
  165.     g_currentLevel++;
  166.     oChildren[iWhichNode]->CreateNode(nodeVerts, iTriangles*3, newCenter, fDiameter/2);
  167.     g_currentLevel--;
  168.  
  169.     delete[] nodeVerts;
  170. }
  171.  
  172. void czOctree::SetNode(D3DXVECTOR3 *pVerts, int numVerts)
  173. {
  174.     containsTriangles = true;
  175.     numVerticies = numVerts;
  176.     pVerticies = new D3DXVECTOR3[numVerts];
  177.     ZeroMemory(pVerticies, sizeof(D3DXVECTOR3)*numVerticies);
  178.  
  179.     memcpy(pVerticies, pVerts, sizeof(D3DXVECTOR3)*numVerticies);
  180. }
  181.  
  182. D3DXVECTOR3 czOctree::GetNodeCenter(D3DXVECTOR3 currentCenter, float fDiameter, int iWhichNode)
  183. {
  184.     D3DXVECTOR3 vCenter = currentCenter;
  185.     D3DXVECTOR3 vNewCenter = D3DXVECTOR3(0.0f,0.0f,0.0f);
  186.     float fDia = fDiameter;
  187.  
  188.     switch(iWhichNode)
  189.     {
  190.         case TOP_FRONT_LEFT:
  191.             {   vNewCenter = D3DXVECTOR3( vCenter.x - fDia/4, vCenter.y + fDia/4, vCenter.z + fDia/4 );
  192.                 break; }
  193.         case TOP_FRONT_RIGHT:
  194.             {    vNewCenter = D3DXVECTOR3( vCenter.x + fDia/4, vCenter.y + fDia/4, vCenter.z + fDia/4 );
  195.                 break; }
  196.         case TOP_BACK_LEFT:
  197.             {    vNewCenter = D3DXVECTOR3( vCenter.x - fDia/4, vCenter.y + fDia/4, vCenter.z - fDia/4 );
  198.                 break; }
  199.         case TOP_BACK_RIGHT:
  200.             {   vNewCenter = D3DXVECTOR3( vCenter.x + fDia/4, vCenter.y + fDia/4, vCenter.z - fDia/4 );
  201.                 break; }
  202.         case BOTTOM_FRONT_LEFT:
  203.             {   vNewCenter = D3DXVECTOR3( vCenter.x - fDia/4, vCenter.y - fDia/4, vCenter.z + fDia/4 );
  204.                 break; }
  205.         case BOTTOM_FRONT_RIGHT:
  206.             {   vNewCenter = D3DXVECTOR3( vCenter.x + fDia/4, vCenter.y - fDia/4, vCenter.z + fDia/4 );
  207.                 break; }
  208.         case BOTTOM_BACK_LEFT:
  209.             {   vNewCenter = D3DXVECTOR3( vCenter.x - fDia/4, vCenter.y - fDia/4, vCenter.z - fDia/4 );
  210.                 break; }
  211.         case BOTTOM_BACK_RIGHT:
  212.             {   vNewCenter = D3DXVECTOR3( vCenter.x + fDia/4, vCenter.y - fDia/4, vCenter.z - fDia/4 );
  213.                 break; }
  214.     }
  215.  
  216.     return vNewCenter;
  217. }
  218.  
  219. void czOctree::Release( )
  220. {
  221.     if(pVerticies)
  222.     {
  223.         delete[] pVerticies;
  224.         pVerticies = NULL;
  225.     }
  226.  
  227.     for(int i=0; i<8; i++)
  228.     {
  229.         if( oChildren[i] )
  230.         {
  231.             oChildren[i]->Release( );
  232.             oChildren[i] = NULL;
  233.         }
  234.     }
  235. }
  236.  
  237. void czOctree::Create(D3DXVECTOR3* pVerts, int iNumVerticies)
  238. {
  239.     numVerticies = iNumVerticies;
  240.  
  241.     SetData(pVerts, iNumVerticies);
  242.  
  243.     CreateNode(pVerts, numVerticies, center, diameter);
  244. }
  245.  
the offending line is:
Expand|Select|Wrap|Line Numbers
  1. oChildren[iWhichNode] = new czOctree;
  2.  
Line 163 from the source.

Any small level of impressiveness that might've been achieved by this code is negated by the fact that I did it following very closely this guide on xbdev.net: http://www.xbdev.net/maths_of_3d/octree/tutorial/index.php

The output from debug reads:
Expand|Select|Wrap|Line Numbers
  1. First-chance exception at 0x7c91b3fb in zombie1.exe: 0xC0000005: Access violation reading location 0x44080000.
  2. First-chance exception at 0x7c81eb33 in zombie1.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x0012fbc4..
  3. Unhandled exception at 0x7c81eb33 in zombie1.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x0012fbc4..
  4.  
I'm fairly sure the error in code is here and not in the implementation from the engine, and so I've neglected to post that here. Mostly because I was able to call new on the bool arrays which precede this call. I added the lines:

Expand|Select|Wrap|Line Numbers
  1. delete[] pBoolArray1;
  2. ...
  3. delete[] pBoolArray8;
  4.  
which were not present in the original source at xbdev.net. Not that I assumed I was a better programmer but because I thought it was right. Even commenting this out I get the same error at the same location.

Please forgive my poor programming style. I am pretty noobish.

If anyone can help me narrow down my problem I'd be greatly appreciative. If you've read this far, I thank you for reading this cumbersome post ^^;;

-Ally
Jun 20 '07 #1
Share this Question
Share on Google+
4 Replies


P: 2
Following some leads I found on the net, and it would seem this would mean I have run out of memory. Is it possible it's from all those boolean arrays? This recursive function is not getting to deallocate those arrays before moving on to the deeper iterations...

Just a thought.
Jun 21 '07 #2

P: 18
Expand|Select|Wrap|Line Numbers
  1.  
  2.  
  3. ASSERT(iTriangles*3 >=NumTotalVerts);
  4.  
  5.  D3DXVECTOR3* nodeVerts = new D3DXVECTOR3[iTriangles*3];
  6.     int count = 0;
  7.  
  8.     for(int i=0; i<NumTotalVerts; i++)
  9.     {
  10.         if( pBools[i/3] ) 
  11.         {
  12.             ASSERT(count < iTriangles*3);
  13.  
  14.             nodeVerts[count] = pTotalVerts[i];
  15.             count++;
  16.         }
  17.     }
Try those check.

Your errors means that somehow the memory was corrupted and a runtime check failed. This is likely to be en error created before the allocation that failed. Also the 0XC000005 is an exception throw when accessing memory not in your adress space. Accessing memory that was deleted is marked 0xFEFEFEFE. Memory that is uninitilized is marked 0XCDCDCDCD. I assumed that this error occurs more in release than in debug right? If it does in crash in debug, it should be easy to fix.
Jun 21 '07 #3

weaknessforcats
Expert Mod 5K+
P: 9,197
Your errors means that somehow the memory was corrupted and a runtime check failed. This is likely to be en error created before the allocation that failed. Also the 0XC000005 is an exception throw when accessing memory not in your adress space. Accessing memory that was deleted is marked 0xFEFEFEFE. Memory that is uninitilized is marked 0XCDCDCDCD. I assumed that this error occurs more in release than in debug right? If it does in crash in debug, it should be easy to fix.
This is my feeling also. Besides, I don't think Visual Studio.NET throws a bad_alloc. To do that free memory is down to the amount required to throw the exception. Long before you get into this condition the message box "Windows running low on resources...." has appeared for hours and the hard disc is vibrating your machine acrosss the floor.

Almost certainly the problem is with oChildren[iWhichNode].
Jun 21 '07 #4

P: 18
The thing is that you might have no more RAM available but Windows will get virtually new one for you using its paging file system.

The only thing you really can be short of is a valid range of adress in the adress space. Each program under windows have 2gig of adress space no matter how much RAM you got on your system.

On Windows CE 5.0 the limit is 32 meg per process, even if more RAM is available.

So a new() call can only fails if not enough contiguous addresses are free in the adress space. If there isn't enough RAM at that point, Windows will start moving page of memory to disk to get some RAM free. This is call virtual memory mapping. This is very powerful.

Long before you get into this condition the message box "Windows running low on resources...." has appeared for hours and the hard disc is vibrating your machine acrosss the floor.
Your are totally right. Moving page file to disk in low ressources conditions is very painful to hear :)....
Jun 21 '07 #5

Post your reply

Sign in to post your reply or Sign up for a free account.