Irritating problem with recursion

Hello, I have a recursive function that has been baffling me for quite a while now:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CUSTOM_FRAME* dr_animated::searchbyname(CUSTOM_FRAME* pFrame, LPCSTR names, size_t length)
{
	if ( !strncmp( names, pFrame->Name, length) )
	{
		MessageBox(NULL, "FrameName:", "Hitbox Editor", MB_OK);
		MessageBox(NULL, pFrame->Name, "Hitbox Editor", MB_OK);
		MessageBox(NULL, "OtherName:", "Hitbox Editor", MB_OK);
		MessageBox(NULL, names, "Hitbox Editor", MB_OK);
		
		return pFrame;
	}
	else
	{
		if (pFrame->pFrameSibling)
			searchbyname((CUSTOM_FRAME*)pFrame->pFrameSibling, names, length);

		if(pFrame->pFrameFirstChild)
			searchbyname((CUSTOM_FRAME*)pFrame->pFrameFirstChild, names, length);	
	}

	return NULL; ///This always results in a crash, but I know that and keep it in temporarily.
}



Basically what it does is go through every frame (bones of an armature), looking for which one has a name which is identical to the passed value 'names' (I called it that because I thought calling it "name" was the reason for the problem, which it wasn't).

What happens is, upon calling it, the MessageBoxes appear (for instance, if names = "Animation_Bone_008", the boxes display:

FrameName:
"Animation_Bone_008" - meaning there IS a pFrame node with that Name.
OtherName:
"Animation_Bone_008" - Which confirms that 'names' was in fact "Animation_Bone_008"

Now here's the issue. After displaying those messages, I expect the function to return a pointer to the bone it found a match for, or, if it didn't, to go on until it does (or crash if it's not there).

It does not. Instead, after calling the function, I always get the exact same return if there IS a match, and a crash if there isn't.

What is returned is a Frame with the name "Animation_Bone_L_007", which is a completely random and unrelated frame.

I have no idea why this is happening, especially since the MessageBox's run, implying that the match was found. Any help is appreciated, thankyou.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CUSTOM_FRAME* dr_animated::searchbyname(CUSTOM_FRAME* pFrame, LPCSTR names, size_t length)
{
	if ( !strncmp( names, pFrame->Name, length) )
	{
	    // ...
		return pFrame;
	}
	
	else
	{
            CUSTOM_FRAME* temp = searchbyname((CUSTOM_FRAME*)pFrame->pFrameSibling, names, length);
            if( temp != nullptr ) return temp ;
        
		else if(pFrame->pFrameFirstChild)
			return searchbyname((CUSTOM_FRAME*)pFrame->pFrameFirstChild, names, length);	
	}

	return NULL; ///This always results in a crash, but I know that and keep it in temporarily.
}

No, sorry that didn't work.

"Unhandled exception at 0x00f95abc in Prac1b.exe: 0xC0000005: Access violation reading location 0x00000000."

And Visual Studio claims the issue to be with the 3rd line in the above code.

Also, I had to replace nullptr with NULL. For some reason Visual Studio didn't recognise it. I later tried it with "if ( !strncmp( names, temp->Name, length) ), and that didn't work either.

Thanks anyway though.
Last edited on
Sorry about that; omitted the check for presence of a sibling.
1
2
3
4
5
6
7
8
9
10
11
12
13
// ...
	else
	{
            CUSTOM_FRAME* temp ;
           
            if(pFrame->pFrameSibling)
                      temp = searchbyname((CUSTOM_FRAME*)pFrame->pFrameSibling, names, length);
            if( temp != nullptr ) return temp ;
        
		else if(pFrame->pFrameFirstChild)
			return searchbyname((CUSTOM_FRAME*)pFrame->pFrameFirstChild, names, length);	
	}
// ... 
It keeps complaining that "temp" is being used without being initialized (when I change nullptr to NULL), and if I keep 'nullptr' the way it is, Visual Studio calls it an 'undeclared identifier'.
Replace nullptr with 0 (or NULL)
1
2
3
4
5
6
7
8
9
10
11
12
13
// ...
	else
	{
            CUSTOM_FRAME* temp = 0 ;
           
            if(pFrame->pFrameSibling)
                      temp = searchbyname((CUSTOM_FRAME*)pFrame->pFrameSibling, names, length);
            if( temp != 0 ) return temp ;
        
		else if(pFrame->pFrameFirstChild)
			return searchbyname((CUSTOM_FRAME*)pFrame->pFrameFirstChild, names, length);	
	}
// ...  
Last edited on
THANKYOU!

Finally, it works!

Although it did take a bit of tweaking to get your code to work:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
	{
        CUSTOM_FRAME* tempsib = 0;
           
        if(pFrame->pFrameSibling)
        tempsib = searchbyname((CUSTOM_FRAME*)pFrame->pFrameSibling, names, length);
        
	if( tempsib != 0 && !strncmp( names, tempsib->Name, length) )
	return tempsib;

		
	CUSTOM_FRAME* tempchil = 0;

	if(pFrame->pFrameFirstChild)
	tempchil = searchbyname((CUSTOM_FRAME*)pFrame->pFrameFirstChild, names, length);

	if( tempchil != 0 && !strncmp( names, tempchil->Name, length) )
	return tempchil;

	}
Last edited on
Topic archived. No new replies allowed.