-
Memory Corruption
Hi everyone.
I've memory corruptions that happens once in a while in random places of my code. One of those places looks like the one below...
Code:
Viewport *pViewport; // initialize pViewport IS ALWAYS a valid viewport
pViewport->getTransformation( TRUE )->unMap(
&m_origin,
pViewport->getBounds()
);
The program crash in pViewport->getTransformation since pViewport is unresolved.
The problem is I've stepped through the debugger a lot of times and make sure that the program execute in exactly the following order
Code:
1. // initialize pViewport
2. pViewport->getBounds(){return this->m_bound; /* a valid rect structure*/ }
3. pViewport->getTransformation(); // missing pViewport here... pViewport suddenly points to 0x000000c once in a while
4. pTransformation->unMap();
BUT when executing getBounds, pViewport is STILL valid, but when executing getTransformation(), pViewport disappeared causing access violation ending in crash.
Is there anyway around this problem? Could it be caused by my bad coding habit rather than "memory corruption" which I presumed? The access violation happens once in a while (once after millions of loops maybe) and it always occur in different places (rarely hit the same place). However, it always happen in situation resembling the one above ( missing reference suddenly)
Thanks a lot for the help!
-
Does it work better if you don't chain three calls at once, but use temporary variables to hold the returned pointers?
Getting a value of 0x0000000C is a fairly clear indication of uisng a null-pointer [+ a bit of offset], which is generally not a good thing to do.
--
Mats
-
Thanks for the prompt reply, matsp!
I would change my call mechanism, however, in other instances it did not happen in chained calls but on the subsequent calling statement. I decide to post the chaining sample to demonstrate that the pointer becomes invalid right after the statement where it was valid.
And sometimes, it crash with the message "access violation reading location 0xXXXXX" or "instruction at memory location 0xXXXXX cannot be read" where XXXXX (values other than 0) reads as "expression cannot be evaluated" in the debugger. Does the two error message means the same? It sounds similar to me.. :(
-
The problem with "chained calls" like that is that they are horribly hard to debug - because the intermediate results are not stored anywhere, so there is no way to look at them after the return of the function. I'm sure the compiler isn't getting it wrong, but YOU may not see a NULL-pointer somewhere in the sequence. [Not to mention that it is hard to debug chained calls even when each individual call goes right, and a good optimizing compiler will give the same or very similar resulting code for temporary variables as it does for chained calls almost every time - because the compiler can not produce the call-chain without some temporary storage of some sort or another anyways].
As to your question regarding the two error messages: yes and no.
The message saying "memory at address X can not be read" means that you are trying to read memory that has no virtual to physical mapping. A read in this case usually means that you are doing "p->x", where p is not a valid pointer (e.g. NULL or some rather random value).
The message saying "instruction at address X can not be read" is essentially the same problem, but in this case, you are trying to EXECUTE (call a function) that is at an invalid memory address. "p->func()" where func is a virtual method would cause this to happen.
--
Mats
-
Wow., thanks very much matsp! Now that I know the difference, I will go back and check each specific logs.
In simple-minded understanding, p->function() will generate "memory at address X can not be read" when p is invalid, but will generate "instruction at address X can not be read" where function() is a virtual method cannot be read.., but when will a virtual method cannot be read? the compiler will tell when the virtual method is not implemented.