default destructors access violation

I have a program where one class has an object of another class as a member. There is an object of the first class as a global variable. When the program closes on the closure of the main window and the default destructors are called (on the uninitialised objects), I recieve an access violation. The problem can be solved by removing the object of the second class from the first class. I would prefer not to do this, or at least I would prefer to know why I have to do this!

The above scenario is not doomed to failure and there are specific features of my code that is causing the problem. If needed I can post the code, but am now off to bed. Any ideas?

(Searching has indicated that others have had similar problems, and one stand out is that a double delete is going on. If this is the case, what circumstances cause this since I cannot replicate the problem in simple codes!).

Thanks!
Hey fellow exiled Aussie :). Is this the sort of situation you're talking about?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// First class, just keeps an int variable
class Class1
{
public:
	Class1() {}
	~Class1() 
	{
	}
	
private:
	int data;
};

// Second class. Keeps an instance of the first class.
class Class2
{
public:
	Class2() {}
	~Class2() 
	{
	}
private:
	Class1 class1Member;
};

// Global variable of Class2
Class2 globalC2;

int main()
{
	// globalC2 = Class2(); // Uncomment if we want to initialise globalC2

	// do something

	return 0;
}


If that's the kind of thing you're talking about, I can't reproduce it. You said that it happens when the global variable isn't even initialised? Why would the destructor then be called when the program terminates? I set breakpoints at both destructors in the code above, and they didn't get hit. If one initialises the global variable in main, then the destructors get hit. Perhaps others know more about this case than me, but I'd need to see your code...
there is a simple solution for this use friend function and make class 2 as friend of class 1
Wow, amit0991, how could you solve a problem that you don't have enough information to even start
thinking about? I, like sammy34, need more information before being able to venture a guess.
Thanks sammy34 - what you posted has caused me to solve the problem, though I still am not certain what the problem was! Sadly I still cannot reproduce the problem in simple code, but an overview of the complete code is included below if it is of interest to others.

The situation was almost as written, except that I did not explicitly include the destructors (I just let the automatic destructors do their work), there was a single initialised (by which I mean it had an assigned value) boolean variable in the constructor of the second class, and I was making a windows app and the second class includes, among other things, a third user defined class as shown in the code below. When I do explicitly include the destructors in the class the problem disappears (thanks again!). Whenever I tried to reproduce the problem in simpler situations, the failure to explicitly include destructors doesn't matter.

I guess alls well that ends well. But if anyone can verify the lack of explicit destructors can cause access violations or an explanation as to why this is, I would be happy to learn!

///////////////////////////////////////
...
class PDAG
{
public:
PDAG();
PDAG(int nodeNum,int valueSize);
PDAG(DAG& dag);

void clear();
void remove(int node);

bool constV;
set<int> nodes;
map<int,set<int>> neigh; // nodes connected by undirected edge
map<int,set<int>> adj; // nodes connected by any edge
map<int,set<int>> par; // parents
map<int,set<int>> chi; // children
map<int,vector<int>> vals; // possible values for each variable
};

class LS
{
public:
LS();
bool check();
void loadData(tstring filename);
multiset<map<int,int>>& getData(); //note return by reference
DAG learn(int thread);

PDAG pdag;
private:
int ess;
bool firstlearn;

map<int,map<int,map<int,double>>> dirLib; //node,parent combo,value,dir int
multiset<map<int,int>> data; // map rather than vector permits any naming for nodes

void GESplus(double score,double& best);
void GESminus(double score,double& best);
bool testValid (int n1,int n2,set<int> setT);
bool clique(set<int> test);
set<set<int>> findSDPs(int n2,int n1);
void findSDPs (set<int> done,int n2, int n1,set<set<int>>& SDPs);
double baseB(int nodeNum);
double scoreB(int node,set<int> parentSet);
double sumDirValues(int node, int pRow,set<int> posParSet);
int sumData(int node,int pRow,set<int> posParSet);
int getData(int node,int value,int pRow,set<int> posParSet);
bool pRowChecker (int node,int pRow,set<int>& posParSet,map<int,int>& datum);
map<int,int> findKey(int node,int pRow);
vector<int> getValNumKey(set<int>& posParSet);
DAG nextDAG(pair<int,int>& tracker,set<int>& bestSet);
DAG nextDAGminus(pair<int,int>& tracker,set<int>& bestSet);
void LS::makeDirLib (); //TO DO:NOT ACTIVE
map<int,map<int,vector<pair<double,double>>>> LS::createRP(DAG& dag);
double LS::variance(double a,double b);
};

class WFRAME
{
public:

WFRAME();

void init(HINSTANCE hinstance);
void regWin(HINSTANCE hinstance,WNDCLASSEX wc,tstring name,WNDPROC wproc,LPWSTR menu);

HWND dis1;// display1
HWND dis2;// display2
HWND dat1;// data1
HWND dat2;// data2

pair<int,int> send1;
pair<int,int> send2;
pair<int,int> send3;
pair<int,int> send4;

vector<int> store;

HWND menu;

LS ls;
};

WFRAME wf;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
nCmdShow=SW_SHOW;
MSG Msg;
HWND parent;

regWin(hInstance,_T("WCPAR"),ParProc,MAKEINTRESOURCE(IDR_MENU1));
RECT rect;
SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);
parent = CreateWindowEx(WS_EX_CLIENTEDGE,_T("WCPAR"),_T("Bayesian Network AI"),WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME,rect.left, rect.top,rect.right-rect.left,rect.bottom-rect.top,NULL, NULL, hInstance, NULL);
if(parent == NULL){MessageBox(NULL, _T("Window Creation Failed!"), _T("Error!"),MB_ICONEXCLAMATION | MB_OK);}
ShowWindow(parent, SW_SHOW);
UpdateWindow(parent);

// The Message Loop
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}

extern WFRAME wf;

LRESULT CALLBACK ParProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
{
RECT rect;
GetClientRect(hwnd,&rect);

regWin(GetModuleHandle(NULL),_T("WCDIS1"),DisProc1,NULL);
HWND dis1win=chiWIN(_T("WCDIS1"),rect.right*.3,rect.top,rect.right*.7,rect.bottom/2,hwnd,(HMENU)IDC_DIS1WIN,_T("DISPLAY THREAD ONE"),(HMENU) IDC_DIS1TIT);

regWin(GetModuleHandle(NULL),_T("WCDIS2"),DisProc2,NULL);
HWND dis2win=chiWIN(_T("WCDIS2"),rect.right*.3,rect.bottom/2,rect.right*.7,rect.bottom/2,hwnd,(HMENU)IDC_DIS2WIN,_T("DISPLAY THREAD TWO"),(HMENU) IDC_DIS2TIT);

regWin(GetModuleHandle(NULL),_T("WCDAT1"),DatProc1,NULL);
HWND dat1win=chiWIN(_T("WCDAT1"),0,rect.bottom*.7,rect.right*.3,rect.bottom*.15,hwnd,(HMENU)IDC_DAT1WIN,_T("DATA THREAD ONE"),(HMENU) IDC_DAT1TIT);

regWin(GetModuleHandle(NULL),_T("WCDAT2"),DatProc2,NULL);
HWND dat2win=chiWIN(_T("WCDAT2"),0,rect.bottom*.85,rect.right*.3,rect.bottom*.15,hwnd,(HMENU)IDC_DAT2WIN,_T("DATA THREAD TWO"),(HMENU) IDC_DAT2TIT);

regWin(GetModuleHandle(NULL),_T("CON1"),ConProc1,NULL);
wf.menu=chiWIN(_T("CON1"),0,0,rect.right*.3,rect.bottom*.7,hwnd,(HMENU)IDC_CON1WIN,_T("CONTROL MENU"),(HMENU) IDC_CON1TIT);
break;
}
case WM_SIZE:
{
//TO DO
break;
}
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDM_FILE_NEW:
{
break;
}
case IDM_FILE_OPEN:
{
break;
}
case IDM_FILE_SAVE:
{
break;
}
case IDM_FILE_CLOSE:
{
break;
}
case IDM_FILE_EXIT:
{
break;
}
}
break;
}
case WM_CLOSE:
{
DestroyWindow(hwnd);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
Now I cannot even reproduce the problem by erasing the now explicit destructors. Sorry for wasting people's time...
Haha all good mate. Glad I was able to help :)...
Topic archived. No new replies allowed.