Sign in to follow this  
monkeyboi

_BLOCK_TYPE_IS_VALID

Recommended Posts

I encounter this assertion while I am trying to free up my program.

Debug Assertion Failed!
File f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp
Line: 52
Expression:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

After setting breakpoint. I found these assertion happended just after the calling of destructor of my encapsulated class MyDxRenderer which is derived from MyRenderer class. However the program never get into the destructor of base class, MyRenderer. This is proven by set a breakpoint in its destructor, I am not sure if this is the right way. Usually the bass class's destructor will be called automatically just after derived class's. Meanwhile I search about the reasons that cause _BLOCK_TYPE_IS_VALID assertion. An common reason is re-delete an invalid block of memory. So I double check my program there are 2 classed that each holds a static pointer of MyRenderer and none of them do any delete operation on it renderer pointer. So how could it be possible I do re-delete?


[CODE]
void MyWindowApplication::OnTerminate ()
{
if (m_pkRenderer)
delete m_pkRenderer;// Reach this breakpoint
m_pkRenderer = 0;
}
[/CODE]


[CODE]
MyDxRenderer::~MyDxRenderer(){
int i;// Reach this breakpoint
for (i = 0; i < m_iMaxTextures; i++)
m_pqDevice->SetTexture(i,0);
for (i = 0; i < m_apTextureNames.GetQuantity(); i++)
{
delete m_apTextureNames[i];
}
}
[/CODE]

[CODE]
MyRenderer::~MyRenderer(){
SetCamera(NULL);// Can not reach this breakpoint
}
[/CODE]

Any suggestion will be highly appreciated.

Jerry

Share this post


Link to post
Share on other sites
I find that when I have a potential double delete issue focused in a very small piece of code, I simply add prints to trace which pointers get freed. In terms of your code, I'd probably throw in something like

[CODE]
void MyWindowApplication::OnTerminate ()
{
printf("Deleting renderer ptr %p", m_pkRenderer);
delete m_pkRenderer;// Reach this breakpoint
m_pkRenderer = 0;
}

MyDxRenderer::~MyDxRenderer(){
int i;// Reach this breakpoint
for (i = 0; i < m_iMaxTextures; i++)
m_pqDevice->SetTexture(i,0);
for (i = 0; i < m_apTextureNames.GetQuantity(); i++)
{
printf("Deleting texture %p", m_apTextureNAmes[i]);
delete m_apTextureNames[i];
}
}
[/CODE]

Logging those pointers, and checking that none of the values printed are identical, I can confirm that indeed there is no double free.

Then, the next thing to check is that you're not freeing a garbage pointer. I'd trace the pointer values I got for memory allocations, and compare them to the freed ones, to see that they match. Something to also check are the actual pointer values: check that the pointer is not something like 0xDDDDDDDD (see [url="http://www.highprogrammer.com/alan/windev/visualstudio.html"]this page[/url]). Also check the this pointer of the class instance that's deleting memory, that you're actually in a valid instance of a class deleting a valid piece of member data.

Share this post


Link to post
Share on other sites
[font=arial,helvetica,sans-serif][size=4]Hi clb[/size][/font]

[font=arial,helvetica,sans-serif][size=4]I have checked the pointer using both of the ways. Firstly the pointer is valid. I can track the adress is 0x0074998 and I can even call a function using this pointer, like m_pkRenderer->BeginScene(); Meanwhile I set a breakpoint at the line [color=#000088]delete[/color][color=#000000] m_apTextureName[/color]s[i] to see if it has been called before terminate the program. So as I continue debugging, the assertion pop out and the cursor will point to the end of destructor function where is below the for iteration and never get into its base class's destructor.[/size][/font]

[color=#660066]MyDxRenderer[/color][color=#666600]::~[/color][color=#660066]MyDxRenderer[/color][color=#666600](){[/color]
[color=#000088]int[/color][color=#000000] i[/color][color=#666600];[/color][color=#880000]// Reach this breakpoint [/color]
[color=#000088]for[/color][color=#000000] [/color][color=#666600]([/color][color=#000000]i [/color][color=#666600]=[/color][color=#000000] [/color][color=#006666]0[/color][color=#666600];[/color][color=#000000] i [/color][color=#666600]<[/color][color=#000000] m_iMaxTextures[/color][color=#666600];[/color][color=#000000] i[/color][color=#666600]++)[/color]
[color=#000000]m_pqDevice[/color][color=#666600]->[/color][color=#660066]SetTexture[/color][color=#666600]([/color][color=#000000]i[/color][color=#666600],[/color][color=#006666]0[/color][color=#666600]);[/color]
[color=#000088]for[/color][color=#000000] [/color][color=#666600]([/color][color=#000000]i [/color][color=#666600]=[/color][color=#000000] [/color][color=#006666]0[/color][color=#666600];[/color][color=#000000] i [/color][color=#666600]<[/color][color=#000000] m_apTextureNames[/color][color=#666600].[/color][color=#660066]GetQuantity[/color][color=#666600]();[/color][color=#000000] i[/color][color=#666600]++)[/color]
[color=#666600]{[/color]
[color=#000088]delete[/color][color=#000000] m_apTextureNames[/color][color=#666600][[/color][color=#000000]i[/color][color=#666600]];[/color]
[color=#666600]}[/color]
[color=#666600]}//cursor stops here[/color]

Share this post


Link to post
Share on other sites
The message comes because of memory corruption. Specifically this one happens from stomping on the header of a block allocated by new.

This particular message comes because you have overwritten the first parts of that header with bad data. When the runtime library attempts to reclaim the memory it finds invalid data in the memory header and asserts.

The most likely cause it that somewhere in your app you are writing past the end of a buffer, or you are writing before the beginning of a buffer. Either way, you are overwriting memory you should not.

Not much of a help, I know. If it is always the same object that gets corrupted, a memory breakpoint on the memory block header should catch it. Otherwise it is guess-and-check with memory breakpoints until you happen to find it. Memory stomps can be a nighmare to find. Edited by frob

Share this post


Link to post
Share on other sites
Thanks frob

Could you please give me more examples about "you are writing past the end of a buffer, or you are writing before the beginning of a buffer. "

Jerry

Share this post


Link to post
Share on other sites
[quote name='monkeyboi' timestamp='1339715400' post='4949349']
Could you please give me more examples about "you are writing past the end of a buffer, or you are writing before the beginning of a buffer. "[/quote]

Overwriting past the end of a buffer:
int* ptr = new int[5];
ptr[5] = 0; <--- BUFFER OVERRUN. You only allocated for elements 0..4, not element 5.
ptr[-1] = 0; <--- This wrote before the buffer instead of after it.
delete[] ptr;
ptr[0]=0; <--- Overwriting memory you no longer own. For all you know that memory has been reclaimed.

Alternatively, you could be attempting to delete something never allocated with new, which will also give a similar error.

A more real-world example would look more like this:

uint8_t* buffer = new char[MAX_BUFF_LEN];
LoadModel(filename, buffer); // Unfortunately the 300kb model is bigger than the 20kb buffer length, so 280kb of memory gets tromped on.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this