?
Solved

HELP!!!!!! IsValidHeapPointer

Posted on 2003-02-23
12
Medium Priority
?
4,149 Views
Last Modified: 2007-12-19
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(PUserData)"
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.
0
Comment
Question by:TheShark8
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
12 Comments
 

Assisted Solution

by:bodoke
bodoke earned 100 total points
ID: 8002661
It means you have a pointer/memory problem somewhere in your application. For example, if you delete a dynamically allocated block of memory twice, the second will fire the assert.
The error means you are doing something to a pointer to heap memory which is no longer valid.
0
 
LVL 22

Accepted Solution

by:
nietod earned 100 total points
ID: 8002704
right.  

Other possible causes (other than deleting the same memory twice) would include trying to delete memory that was never allocated, like

const char *AString = "abcdef";

delete [] AString;

or deleting a pointer that is not a pointer to the _start of_ a dynmically allocated block.   Like

char *AString == new char [10];

for (int i = 0; i < 5; ++i)
   *AString++ == 'a';

delete [] AString;

(This alters AString so it points to a character in the middle of the allocated memory, not the start, so the delete fails.)


When you get this alert, you will be inside a procedure in the C++ runtime library.  i.e. not a procedure you've written.  But that procedure is called (ultimately) from code you've written.  you should look at the call stack (in the variables window).  It lists the procedure you are currently in, the procedure that called that one, the procedure that called that one and so on until main (the bottom of the call stack).  So look through the call stack until you find a procedure that you wrote.   Look at that procedure, its likely the problem is there.  (That procedure shoudl be calling delete, delete [] or free().   If the pointer that procedure is trying to delete with is passed to that procedure, then the problem might be in the procedure that calls it.  Again you might have to move down the call stack until you reach a procedure that is really responsible for the problem.
0
 
LVL 22

Expert Comment

by:grg99
ID: 8003416
What I've done in hard cases where there's soem kind of pointer error, I write wrappers for malloc and free.

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

 
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 22

Expert Comment

by:nietod
ID: 8003526
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.

0
 
LVL 2

Expert Comment

by:bkrahmer
ID: 8031632
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
0
 
LVL 22

Expert Comment

by:nietod
ID: 8032882
>>  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....
0
 
LVL 2

Expert Comment

by:bkrahmer
ID: 8034973
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
0
 
LVL 22

Expert Comment

by:nietod
ID: 8035223
>> 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.
0
 
LVL 2

Expert Comment

by:bkrahmer
ID: 8038910
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
0
 
LVL 22

Expert Comment

by:nietod
ID: 8041116
>> 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.
0
 
LVL 11

Expert Comment

by:bcladd
ID: 9784249
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
0

Featured Post

New benefit for Premium Members - Upgrade now!

Ready to get started with anonymous questions today? It's easy! Learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question