• Advertisement

Archived

This topic is now archived and is closed to further replies.

I can't delete a perfectly valid piece of memory!

This topic is 5744 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a block of memory, and it creates an error when I try to delete it (regardless of whether I use delete or free). But, oddly, it appears to be perfectly valid otherwise - I can edit its contents, and _msize returns the correct size. It''s an array of 312 words, and _msize returns 624, perfectly correct. What can cause this? If it matters, the array is an array of indices used eventually for glDrawElements. ~CGameProgrammer( );

Share this post


Link to post
Share on other sites
Advertisement
For one thing, there is no confusion. I use delete. I just tried free for debugging purposes.

As for the code, I can''t show it because it''s my entire project. The part of the code that the error occurs in won''t help any because the block of memory is allocated/deallocated elsewhere and it''s always worked perfectly fine before.

Basically, the problem is what I stated. The memory block is valid and can be read from, but it can''t be deleted. It also cannot be debugged. When that "Click Retry to debug" dialog box appears, clicking any of its buttons causes a new instance of the same message box to appear, ad infinitum. I have to use Ctrl+Alt+Del to close the application. But I did find out which part of the code caused the error, and I tested the block of memory and found out the correct size was reported with _msize.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites
1) did you new [] the memory?
2) did you delete [], and not delete the memory (not the same thing)?
3) are you sure the delete is causing the error, and its not because you are trying to access the memory after its been deleted (set the pointer to 0 after delete)?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Are you creating the memory in a different thread or process? Memory created in a .DLL and then used in a different process can be tricky to delete correctly, as you need to make sure the pointer to the memory location is returned corretly.

It''s difficult to help you with this problem when the details about how the memory is allocated is so vague.

Share this post


Link to post
Share on other sites
Double deletion might also causes problems. Or r u deleting some pointers (or references) to an automatic variables acidentally??

Share this post


Link to post
Share on other sites
You are almost certainly invoking undefined behaviour along the way, most probably corrupting the heap. You might be over-writing array bounds somewhere, which can certainly cause what you are seeing.

Share this post


Link to post
Share on other sites
I agree with SabreMan. You are most likely corrupting the heap somewhere else and that will in many cases cause what you are describing. I have tried this once before in a larger project and it is a pain to find the error. Also, make sure you are always setting the pointer to zero after deleting it, which will ensure you are not double-deleting (calling delete on a null pointer will do nothing).

René

Share this post


Link to post
Share on other sites
quote:
Original post by Spartacus
Also, make sure you are always setting the pointer to zero after deleting it, which will ensure you are not double-deleting (calling delete on a null pointer will do nothing).

I''d be careful with offering this advice. If you don''t want or expect an object to be deleted twice, and you nullify a pointer to allow it, you are covering up the real problem. It''s usually only worth nullifying pointers where it enables functionality.

Share this post


Link to post
Share on other sites
SabreMan:
That''s true what you just said, and actually it isn''t really the way I usually do it either. When I delete a pointer, I use a macro I''ve made called SAFE_DEL used to delete for instance pointers to class objects, and SAFE_DELARR to delete pointers to arrays. The macro then uses the assert macro on the pointer, and if the pointer is NULL it will give me an error and will not delete the pointer. By setting the pointer to zero after deleting it, that will ensure that im not deleting it twice.

I agree with you that deleting a pointer twice, even if deleting the pointer the second time does not have any effect, is not good practice.

René

Share this post


Link to post
Share on other sites
I''m not sure about different OS''s, but I''m pretty sure you can write to your application''s memory space without allocating it. Your OS will only complain if you write outside the memory IT allocated for your program.

For example, your OS may allocate 1M for your program, even if you''re only using 100K. If you write/read anywhere in that 1M, the OS won''t care, even though you didn''t allocate it with malloc. But, you could be writing anywhere. Unallocated memory. Allocated data. Or even overwrite your programs instructions.

Is my understanding of this correct?

Share this post


Link to post
Share on other sites
quote:
Original post by Thrump
Is my understanding of this correct?

Basically. The OS doesn''t immediately notify you of "overrun array bounds" or anything like that, bu it''s generally a Very Bad Thing (the exceptions being extraordinary hacks).

Share this post


Link to post
Share on other sites
sure you can write to any memory that your app controls, including corrupting other varibles your app uses, corrupting the stack, screwing up dx or opengl states, vtables of your objects, etc. NEVER assume out of bound array access is "safe" when it dont crash. in ALL cases, the app not crashing is cause for greater concen when you are accessing data outside the bounds of the memory block you are working with. you never know what your corrupting.

Share this post


Link to post
Share on other sites
I use new and delete/delete[] correctly. And the pointer is never deleted if NULL, and always set to NULL after being deleted. And as I said, the size of the memory block is correct so obviously it''s not an invalid pointer.

The data in question is an array of indices for OpenGL, and the Direct3D code has something just like it, except it''s an index buffer instead of a word array. The Direct3D version works. But, maybe there is some bad memory writing going on somewhere. After all, it is odd that the vertex array has no problems but the index array does.

My question is, if a bad memory write elsewhere corrupted the data of the word array, might that still allow _msize() to return the correct size? Because it does.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
What exactly is the error you''re getting?

Does it happen the name in release mode and debug mode?

Share this post


Link to post
Share on other sites
Also it works fine if I don't delete the index array, though this means there's unfreed memory when the program quits.

~CGameProgrammer( );

EDIT: The error, when in debug mode, is this:
DAMAGE: after Normal block (#22408) at 0x0823BB50.

I probably should have mentioned that earlier I guess that means the block of memory has been corrupted?

[edited by - CGameProgrammer on May 30, 2002 3:48:29 PM]

Share this post


Link to post
Share on other sites
If you are using Visual Studio .NET/Visual C++ 7.0, it screams "buffer overrun" to me.

RomSteady - Able to leap off tall buildings in a single bound

Share this post


Link to post
Share on other sites
quote:
Original post by CGameProgrammer
EDIT: The error, when in debug mode, is this:
DAMAGE: after Normal block (#22408) at 0x0823BB50.

I probably should have mentioned that earlier I guess that means the block of memory has been corrupted?



Yeah. You wrote over memory past the end of the allocated array.

MSN

Share this post


Link to post
Share on other sites
its definatly a buffer overrun. _msize woudl return the correct size since that is stored elsewhere away from where the pointer points. instead that information is stored in a table.

Share this post


Link to post
Share on other sites
Ah, I just discovered the error. I had been thinking I must have overwritten the vertex array (allocated before the index array is allocated) and that it corrupted the index array data. But actually I had overwritten the index array by 1 word. Specifically the error was this (the red text is the correction that fixes the error):

for( I = 0; I < NumIndices-1; I += 2 )
{
DestIndices[ I] = PrevVertices + SrcIndices[ I];
DestIndices[I+1] = PrevVertices + SrcIndices[I+1];
}

Dumb me. After I fixed it I went here and saw your message msn, too bad I hadn't known that earlier - it would have saved me a lot of time! I hate memory errors.

Probably the reason it's always worked before was that the number of indices must have always been even. If there were, say, 3 indices, then the old loop would write the first two, then I would be 2, which is less than three, so it would try to write the next two, but there'd only be one left. Oops!

But the Direct3D code used the same loop, yet there were no problems with it. That really threw me off.

~CGameProgrammer( );



[edited by - CGameProgrammer on May 30, 2002 4:34:19 PM]

[edited by - CGameProgrammer on May 30, 2002 4:35:22 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by a person
sure you can write to any memory that your app controls


I never said it was a good idea, or ''safe''. I simply said your OS won''t complain. You could, not should.

Share this post


Link to post
Share on other sites
i know Thrump, i just felt it needed to be clarified slightly as sometimes newbies will read discussions and think of "cool" ways of "optimizing" things by using bad practices.

Share this post


Link to post
Share on other sites

  • Advertisement