Hi everyone, i'm having a very strange and annoying issue on a code i'm working on, i've tried a lot of things but none of them has worked so any help will be greatly appreciated.
Here's the problem:
I'm coding a framework for using custom controls, with the ability of using skin files packed inside a zip file and using xml for the skin definition. I've created some base classes to implement a 'skinned' dialog (wich doesn't seem to give any problem) and another to encapsulate a custom control: this handles painting, responds to mouse/keyboard/focus events and provides the basic skinning support, so i can create a derived class and, by overriding its procedures, receive events and so on.
I've coded label, textbox and button controls to use this framework; the label works without any problem, getting the colors from the skin file. The textbox is a plain window that shows an EDIT window inside when clicked, only the container has painting support, but i can't create two textbox controls on the same dialog or i end up getting an 'Access violation' exception. The button is a 5-state bitmapped control with simple caption, works ok, but has a very strange bug: it has a CRect member (m_rcMargins) to clip drawing and i can't change it or i get an 'Access Violation' too.
The members of the CSkinButton class are:
...
class CSkinButton: public CSkinCtrl {
protected:
CString m_szUIDefId;
COLORREF m_crForeColor;
COLORREF m_crBackColor;
BOOL m_bAutoSize;
UINT m_uStyle;
CRect m_rcMargins;
...
As you can see, none of them are dynamically allocated, so an Access violation doesn't make any sense when trying to modify them from inside the same class code:
...
BOOL CSkinButton::OnSkinChanged()
{
if (m_uStyle == 1)
{
m_uBltMode = 5;
m_pSkin->GetThemeBitmap(_T("button"), _T("background"), m_bmBkgnd);
m_rcMargins.SetRect(3,3,3,3); // This generates an exception!!!
}
...
The control is not dinamically declared on the CDialog-based container, so there isn't any dinamically-allocated memory there, and i'm getting an exception...
There is also another strange thing: I've shuffled the variable positions inside the CSkinButton class declaration because m_uStyle was giving me the same problem, and it was solved by changing its position.
I don't know what's wrong with my code, i've checked everything, i doesn't use any strcpy's or another function that may lead to heap corruption, i'm not using dynamic arrays, but i'm getting those access violations and some 'heap around the variable is corrupted' messages when changing the code.
I'm using zlib, minizip and tinyxml in static libraries, so i don't think they could be causing the problem. There are two projects also: the controls library (static lib) and the test app (exe), i'm working with both of them on a single VS solution, the project dependencies are OK, compiler settings, etc.
I don't want to have to re-write the entire library, but i don't know what to do.
There is also another strange thing: I've shuffled the variable positions inside the CSkinButton class declaration because m_uStyle was giving me the same problem, and it was solved by changing its position.
Changing the order of declaration is changing the order of crashing is highly likely due to a memory corruption.
I don't know what's wrong with my code, i've checked everything, i doesn't use any strcpy's or another function that may lead to heap corruption, i'm not using dynamic arrays, but i'm getting those access violations and some 'heap around the variable is corrupted' messages when changing the code.
Although it sucks, there is a big change that something is overwritting your memory.
You can use AfxCheckMemory to runtime-check for memory problems. Sprinkle the function through your code where you think that something can go wrong to check your memory.
Thanks for the reply, i'll try that but in the meantime, i've added a dummy variable below the m_rcMargins and voila! no more access violation, well, amost. Now i have a debug assertion on 'dbgrpt.c' that leads to another access violation, now in 'cmdtarg.cpp', here's the error line:
CCmdTarget::~CCmdTarget()
{
#ifndef _AFX_NO_OLE_SUPPORT
if (m_xDispatch.m_vtbl != 0)
((COleDispatchImpl*)&m_xDispatch)->Disconnect(); <----- breakpoint is placed there
ASSERT(m_dwRef <= 1);
#endif
m_pModuleState = NULL;
}
And yep, i know that something is modifying memory as you said, the trouble is that i have a lot of lines of code, so debugging this will be a headache. Anyway, thanks again for the reply Skizmo.
Just wondering, could this be caused by a faulty VS?? i have vs2008, no service packs and just a hotfix (KB948127)
Thanks for the reply, i'll try that but in the meantime, i've added a dummy variable below the m_rcMargins and voila! no more access violation, well, amost. Now i have a debug assertion on 'dbgrpt.c' that leads to another access violation, now in 'cmdtarg.cpp', here's the error line:
All you're doing by adding, moving, and removing lines is changing the executable image. That bug is being moved around from place to place. Stop doing this.
Put the lines back that cause the error, and fix the problem. You'll be just wasting your time by messing around with adding and removing lines.. It is always best to have an error you can duplicate, and keep the code so that you can continue to duplicate the error until you fix it. Otherwise, you will just have a hidden bug in your app, and you won't know when, where, or how that bug may pop up again.
It's remotely possible, but it's always best to assume you've done something wrong before looking to place blame elsewhere.
Jajaja!! Thanks for the feedback, i'm pretty sure it's a bug from my own code, i'm checking every line to try to find the cause. Also thanks to VictorN, and to Paul McKenzie: i will try to leave the code 'as is', certainly you're right, but this is driving me crazy!
I have another question: I'm deriving the CSkinButton class from CSkinCtrl and ISmartCtrl: the first class defines and implements some routines to provide the basic interaction and skinning services; the later is an interface wich only defines a couple of notification events and a pointer, i'm much of a beginner to OOP, so this may sound foolish but, may the multiple inheritance cause this kind of memory corruption?
I've checked some part of the code and the Access violations are not ocurring during some specific call, they're hopping from constructors to function calls, to variable asignments and to mfc-core classes, i think there's a pointer somewhere that is causing all the issues, but i just can't find it. I have NULL-checks and so on, but this is just freaking me out...
Note: I'm using the AfxCheckMemory() hint, but i'm not getting any output...
Thanks again for the help.
Last edited by bioHzrdmX; July 21st, 2010 at 02:55 PM.
Reason: I forgot this!!
Jajaja!! Thanks for the feedback, i'm pretty sure it's a bug from my own code, i'm checking every line to try to find the cause. Also thanks to VictorN, and to Paul McKenzie: i will try to leave the code 'as is'
Good -- Just don't be tempted to add a line to seemingly get rid of the error. You will be sorry if you do that, since you now have an app that is unstable. It may work for you 1,000 times, and then when you try it on another machine, or you add harmless lines of code, it crashes again.
may the multiple inheritance cause this kind of memory corruption?
Basically anything in C++ that has to do with pointers, arrays, references, classes, and function calls can cause memory corruption. So you can't look at it from that angle as to all the ways memory can be corrupted. There are just too many possibilities, from the simple to the complex. It could be as simple as overwriting an array that can hold only n elements, and you're copying n+1 elements, or it could be the misuse of C++ in some way (returning a pointer or reference to a local variable, for example).
Since we don't have your source code, there is nothing we can do except to tell you to debug more. If we had all of your code and are able to reproduce the bug, then that would be a different story.
Finally i got this fixed, and guess what... It was a faulty pointer in one of the base classes and a .h file not being update (it had the wrong class declarations), but it works now!!
This was a simple mistake causing big problems, this is the part of programming everyone is afraid of, but its kinda funny searching through code, it's great when you get some help from other people with better skills, and even better when you finally find and kill the bug
Thanks Lindley, Skizmo, VictorN and Paul McKenzie for his great and valuable hints.
I'm attaching a capture of how the app looks by now, and thanks to your help it will be finished someday...
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.