TheShark8
asked on
HELP!!!!!! IsValidHeapPointer
Hi,
I have an application that running all the time.
sometimes the application crashes and I get this error (in debug assertion) : dbgheap.c
"_CrtIsValidHeapPointer(PU serData)"
what does this error means?
what could cause this problem?
I have no clue cause sometimes it happens and sometimes it doesn't.
thanks,
TheShark.
I have an application that running all the time.
sometimes the application crashes and I get this error (in debug assertion) : dbgheap.c
"_CrtIsValidHeapPointer(PU
what does this error means?
what could cause this problem?
I have no clue cause sometimes it happens and sometimes it doesn't.
thanks,
TheShark.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
why bother? That is what VC is already doing (in effect).
The debug version of the VC RTL checks ever pointer passed to delete or free to make sure it is a valid heap pointer. In this case it is not and it is reporting that error. Another mechanism that would detect the error isn't needed. We know there is an error. Now you need to find the cause.
The debug version of the VC RTL checks ever pointer passed to delete or free to make sure it is a valid heap pointer. In this case it is not and it is reporting that error. Another mechanism that would detect the error isn't needed. We know there is an error. Now you need to find the cause.
I would just like to state that code should not contain asserts. 99% of the time, anyway. A better solution is to use test-first-design. The test cases are there, the interface is well-established, and you have tests to fall back on if you want to change the code. Give it a try, and I bet your pointer problems will disappear.
brian
brian
>> would just like to state that code should not contain asserts. 99% of the time, anyway.
That's nonsense. asserts are an extremely useful method for performing testing. In particular, asserts excellent for performming invariance testing and parameter testing.
furthermore, this assert is inside the C++ RTL. Its not like TheShark8 can remove it. And the VC programmers obviously think that asserts are useful. And they are. In this case, they are using it for parameter testing....
That's nonsense. asserts are an extremely useful method for performing testing. In particular, asserts excellent for performming invariance testing and parameter testing.
furthermore, this assert is inside the C++ RTL. Its not like TheShark8 can remove it. And the VC programmers obviously think that asserts are useful. And they are. In this case, they are using it for parameter testing....
Goto statements are useful. So are having multiple return statements in one function. Something that is useful does not necessarily imply that it's the best way to do something. Besides that, aborting a program because of one improperly passed variable is a very bad decision most of the time. If I did that in my enterprise application that is supposed to be running 24/7, where does that leave me? This is C++, is it not? There should be specific return values for bad parameters, or structured exception handling used, not asserts. In addition, I have seen people use asserts as reminders of smelly code where an assumption was made and the function was not really finished.
brian
brian
>> Besides that, aborting a program because of one improperly passed
>> variable is a very bad decision most of the time. If I did that in my
>> enterprise application that is supposed to be running 24/7, where
>> does that leave me?
I don't think you understand assert(). Its a testing and debugging too. An assert() won't even be present in a released application--unless you make some unusual choices.
an assert or similar procedure is not only a good way of testign for certain types of errors it is simply the ONLY way to test for them. That is why its use is so important to library designers. And that is why you see it used in the VC library. Think about it. No matter how much testing some library programmer does, no mattter what he/she decides to do. There is NO way to prevent a client from calling a library procedure with incorrect parameters. Only debug-time testing can be used to detect this sort of problem.
>> There should be specific return values for bad parameters, or
>> structured exception handling used, not asserts
Either would be invalid for this case, since delete cannot return a value or throw an exception.
If you are concerned about the life of your program in this case, the assert only notifies the debugger of the problem, that is all. If there is no debugger, there is no alert. And if this occurs under a typical release version, there is no assert code (its conditional code.) And in either case VC handles the problem as elegantly as possible--basically it ignores it. That is about the best that can be done. Throwing an exception to tell you that memory got corrupted is almost pointless. There is no possible way to catch the exception and do something useful about it! that same would be true about a double delete or a delete of an invalid pointer. If you threw an exception, most programs would either be terminated by the exception, or catch it and ignore the problem. Neither is better than VC's choice.
And yes there are many times when a library procedure can inform the caller of an error and where the caller can often take reasonable action. But that is not always the case.
>> In addition, I have seen people use asserts as reminders of smelly
>> code where an assumption was made and the function was not
>> really finished
I have seen programmers that have abused the use of classes, but I'n not going to stop using them either.
>> variable is a very bad decision most of the time. If I did that in my
>> enterprise application that is supposed to be running 24/7, where
>> does that leave me?
I don't think you understand assert(). Its a testing and debugging too. An assert() won't even be present in a released application--unless you make some unusual choices.
an assert or similar procedure is not only a good way of testign for certain types of errors it is simply the ONLY way to test for them. That is why its use is so important to library designers. And that is why you see it used in the VC library. Think about it. No matter how much testing some library programmer does, no mattter what he/she decides to do. There is NO way to prevent a client from calling a library procedure with incorrect parameters. Only debug-time testing can be used to detect this sort of problem.
>> There should be specific return values for bad parameters, or
>> structured exception handling used, not asserts
Either would be invalid for this case, since delete cannot return a value or throw an exception.
If you are concerned about the life of your program in this case, the assert only notifies the debugger of the problem, that is all. If there is no debugger, there is no alert. And if this occurs under a typical release version, there is no assert code (its conditional code.) And in either case VC handles the problem as elegantly as possible--basically it ignores it. That is about the best that can be done. Throwing an exception to tell you that memory got corrupted is almost pointless. There is no possible way to catch the exception and do something useful about it! that same would be true about a double delete or a delete of an invalid pointer. If you threw an exception, most programs would either be terminated by the exception, or catch it and ignore the problem. Neither is better than VC's choice.
And yes there are many times when a library procedure can inform the caller of an error and where the caller can often take reasonable action. But that is not always the case.
>> In addition, I have seen people use asserts as reminders of smelly
>> code where an assumption was made and the function was not
>> really finished
I have seen programmers that have abused the use of classes, but I'n not going to stop using them either.
Nietod, picking apart my argument is not adding anything to this topic. I did forget the fact that asserts are conditionally compiled. Which leads me pointing out that your statement of 'an assert or similar procedure is not only a good way of testign for certain types of errors it is simply the ONLY way to test for them' is bogus. There is only one way to skin this cat, and that is code that will only do checking in debug versions of the code? If it's worth checking in debug mode, it's absolutely worth checking in release mode, IMO. You are correct in stating that throwing an exception to tell you memory is corrupted is pointless. Kind of like using CrtIsValidHeapPointer, isn't it? The whole point of my initial post was mentioning test-first design, and you completely glossed over it. There are problems like handling memory that cannot be easily solved in a fool-proof way. However, with good coding practices, they can be nearly eliminated.
brian
brian
>> If it's worth checking in debug mode, it's absolutely worth checking in release mode, IMO
Yes. and VC does. I only reports the error in debug mode.
>> You are correct in stating that throwing an exception to tell you memory is
>> corrupted is pointless. Kind of like using CrtIsValidHeapPointer, isn't it?
Not really. VC uses CrtIsValidHeapPointer (or its equivalent) to make sure it doesn't corrupt the heap--or at the very least to not further corrupt it. i.e. even in a release mode it won't "delete" a block that determines is not really an allocated block.
Some programmers further use CrtIsValidHeapPointer() in their production code to differentiate between allocated blocks and non-allocated blocks. i.e. you pass can pass a pointer to a procedure or class and if it is for an allocated block, it will eventually be deleted, otherwise not. A debatable choice, but its done nevertheless. (not much of a debate really)
>> The whole point of my initial post was mentioning test-first
>> design, and you completely glossed over it.
That is great, but its not of any value to the programmer that put in that assert. he/she could never test for this error.
Yes. and VC does. I only reports the error in debug mode.
>> You are correct in stating that throwing an exception to tell you memory is
>> corrupted is pointless. Kind of like using CrtIsValidHeapPointer, isn't it?
Not really. VC uses CrtIsValidHeapPointer (or its equivalent) to make sure it doesn't corrupt the heap--or at the very least to not further corrupt it. i.e. even in a release mode it won't "delete" a block that determines is not really an allocated block.
Some programmers further use CrtIsValidHeapPointer() in their production code to differentiate between allocated blocks and non-allocated blocks. i.e. you pass can pass a pointer to a procedure or class and if it is for an allocated block, it will eventually be deleted, otherwise not. A debatable choice, but its done nevertheless. (not much of a debate really)
>> The whole point of my initial post was mentioning test-first
>> design, and you completely glossed over it.
That is great, but its not of any value to the programmer that put in that assert. he/she could never test for this error.
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:
Answered: Points split between bodoke and nietod
Please leave any comments here within the next seven days. Experts: Silence
means you don't care.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
-bcl (bcladd)
EE Cleanup Volunteer
I will leave a recommendation in the Cleanup topic area that this question is:
Answered: Points split between bodoke and nietod
Please leave any comments here within the next seven days. Experts: Silence
means you don't care.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
-bcl (bcladd)
EE Cleanup Volunteer
The wrapper for malloc makes sure the real malloc returns a non MLL pointer, and it enters the pointer in a table of valid pointers.
Our free(0 wrapper does the reverse, it makes sure we're not freeing NUL, plus it checks that what we're freeing is in our valid malloc'ed pointer table.
I've found scads of bugs this way..
Regards,
George