new is returning NULL

Started by
19 comments, last by Sneftel 18 years, 9 months ago
Quote:Original post by Grain
BTW: If it helps any, I put a break point in the OctTree constructor and its not being called on this line: if(Child == NULL){Child = new OctTree;} how ever the other one where the allocation works the constructor is called.


That's an important clue. Does the debugger actually tell you that Child == NULL</tt>? Has <tt>i</tt> got a valid value? Try placing the if-clause and statement block &#111;n separate lines to see whether the call to new actually takes place.
Kippesoep
Advertisement
@snk_kid:let me guess the placement new doesn t initialize the VFT pointer right?


the compiler sets up the VFT pointer as i just read on google

http://www.8ung.at/basiror/theironcross.html
Quote:Original post by Basiror
@snk_kid:let me guess the placement new doesn t initialize the VFT pointer right?


the compiler sets up the VFT pointer as i just read on google


[headshake] I don't think you understood or get the point of my message, for one thing using placement new for pointer types isn't necessary (you can do but its not needed) as pointers are POD-types therefore an array of pointers is also a POD-type.

Secondly in general if you where going to separate allocation/deallocation & construction/destruction for efficiency reasons (as is the case for std::vector) using calloc for your method of allocating uninitialized memory is naive because calloc zero initializes elements of an array. This is pointless if you are going to use placement new because the whole point of placement new is to initialize uninitialized memory properly, a normal method of allocating uninitialized memory is to either use malloc or using operator new via explicit invocation or something similar becasue they both allocate uninitialized memory, no time is wasted as is the case with calloc.
OK this is really weird now;

I rewrote the function a little with some OctTree creations spattered about it.
void OctTree::add_geometry(vector3d* V, unsigned int num_verts, unsigned int *I, unsigned int num_tris){       OctTree *T1 = new OctTree;    verts = V;    index = I;    NumTris = num_tris;    num_tris = 0;    unsigned int *new_I = NULL;    if(Parent == NULL)    {        B.add_points(V,num_verts);    }    if(NumTris > 1)    {        OctTree *T2 = new OctTree;        for(int i = 0; i < 8; i++)        {            OctTree *T3 = new OctTree;            AABB Box = B.eighth(i);            for(unsigned int j = 0; j < NumTris; j++)            {                if( Box.contains(V[I[j*3]]) || Box.contains(V[I[j*3+1]]) || Box.contains(V[I[j*3+2]]))                {                                num_tris++;                }                        }            OctTree *T4 = new OctTree;            for(unsigned int j = 0, k = 0; j < NumTris; j++)            {                if( Box.contains(V[I[j*3]]) || Box.contains(V[I[j*3+1]]) || Box.contains(V[I[j*3+2]]))                {                    if(new_I == NULL)                         new_I = new unsigned int[num_tris];                    new_I[k*3] = I[j*3];    new_I[k*3+1] = I[j*3+1];    new_I[k*3+2] = I[j*3+2];                    k++;                }            }            OctTree *T5 = new OctTree;            if(num_tris > 0)            {                if(Child == NULL)                {                    Child = new OctTree;                }                                    Child->B = Box;                Child->Parent = this;                Child->add_geometry(V, num_verts, new_I, num_tris);            }            num_tris = 0;        }    }}


OctTree *T4 = new OctTree; gets a valid new object;
OctTree *T5 = new OctTree; gets a null pointer;
This is the only code in between them.
 for(unsigned int j = 0, k = 0; j < NumTris; j++)            {                if( Box.contains(V[I[j*3]]) || Box.contains(V[I[j*3+1]]) || Box.contains(V[I[j*3+2]]))                {                    if(new_I == NULL)                         new_I = new unsigned int[num_tris];                    new_I[k*3] = I[j*3];    new_I[k*3+1] = I[j*3+1];    new_I[k*3+2] = I[j*3+2];                    k++;                }            }

I'm not really sure what is the deal here, or what has been said and not...

But I've had the very same problem, did a little bot once... very simple, not complex at all... I had this loop, didn't do anything... created 20 chars... created 20 chars, or not... it returned NULL for the rest of the loops.

I could never figure out what was wrong, after rewriting my app it worked... still could never figure out why it didn't want to allocate memory the second time it got around the loop. I could allocate the memory before, worked great, but second time in the loop simply didn't want to go my way.


OP:

Not sure if this has been mentioned yet (haven't read the whole thread)...

but these two lines seem suspicious to me:

   OctTree *Child[8]; //in the variable declarations//and then   Child = NULL;  // in the constructor


The system should be throwing an access violation at you in the constructor for that... that's why your constructor fails. The throw takes you out of the constructor's code block.

Child is declared as a pointer to an array; since you haven't defined the array, you're attempting to NULL out memory any old place.

Creating the child array would create a circular reference to OctTree's constructor, which would hang indefinitely... and blow the stack eventually.

my_life:          nop          jmp my_life
[ Keep track of your TDD cycle using "The Death Star" ] [ Verge Video Editor Support Forums ] [ Principles of Verg-o-nomics ] [ "t00t-orials" ]
Quote:Original post by Verg
OctTree *Child[8]; //in the variable declarations


Child is declared as a pointer to an array; since you haven't defined the array, you're attempting to NULL out memory any old place.


It's not a pointer to an array, it's an array of 8 pointers.

Kippesoep
Aaaarrrrggggg!!!!!

Fixed it.

Forgot to multiply num_tris by 3 when creating a new index array. I hate it when its something stupid like that.

     for(unsigned int j = 0, k = 0; j < NumTris; j++)            {                if( Box.contains(V[I[j*3]]) || Box.contains(V[I[j*3+1]]) || Box.contains(V[I[j*3+2]]))                {                    if(new_I == NULL)                         new_I = new unsigned int[num_tris*3]; //I forgot that A triangle is 3 unsigned ints.                    new_I[k*3] = I[j*3];    new_I[k*3+1] = I[j*3+1];    new_I[k*3+2] = I[j*3+2];                    k++;                }            }


But why didn’t I get an access violation when I say new_I[j*3+2]?
Quote:Original post by Kippesoep
Quote:Original post by Verg
OctTree *Child[8]; //in the variable declarations


Child is declared as a pointer to an array; since you haven't defined the array, you're attempting to NULL out memory any old place.


It's not a pointer to an array, it's an array of 8 pointers.


Disregard then [smile]

my_life:          nop          jmp my_life
[ Keep track of your TDD cycle using "The Death Star" ] [ Verge Video Editor Support Forums ] [ Principles of Verg-o-nomics ] [ "t00t-orials" ]
Quote:Original post by Grain
But why didn’t I get an access violation when I say new_I[j*3+2]?


Range checking is not implemented in C/C++, especially for dynamic memory. You get an access violation if you're attempting to write to memory that you don't have write access to. In this case, the memory after the array also had write access enabled, which means you can clobber that memory without noticing it at the time.
Kippesoep

This topic is closed to new replies.

Advertisement