Wie vergrössere ich den Stack?
-
Hallo,
wie kriege ich den Stack in MS VC++ 6.0 grösser?
...ich hab gehört, irgendwo unter Linker in den Projekteinstellungen, aber da finde ich nichts...
-
Aus welchem Grund möchtest du den Stack vergrößern?
-
Hast du den Linkerfehler wegen zu großer Klasse?
Dann schau unter der Fehlernummer in die MSDN, da steht, was du eingeben musst.
-
Ich hab immer noch das Problem mit dem Stack Overflow
siehe Beitrag:
http://www.c-plusplus.net/forum/viewtopic.php?t=92239Krieg aber das Problem nicht in den Griff, jetzt konnte ich hier schon in dem Forum nachlesen, dass es zu Rekursionen gekommen sein könnte oder auch das der Stack zu klein ist, und ich ihn vergrössern kann, ich weiss nur nicht, wie? und meine Hilfe unter VC++ funzt auch nicht...
estartu_de schrieb:
Hast du den Linkerfehler wegen zu großer Klasse?
ob er das anmeckert wegen zu grosser Klasse, kann ich Dir nicht sagen, in der Konsole sehe ich nur das:
Nicht abgefangene Ausnahme in API.exe: 0xC00000FD: Stack Overflow.
-
Aus den Angaben, die du da machst kann ich leider nix erkennen.
Du könntest das Projekt ja online stellen und beschreiben, was man machen muss, damit es passiert, dann könnte man besser gucken.
-
Starte das Programm mal im Debugger und zeig uns den Callstack (Aufrufliste), wenn der Overflow auftritt.
-
also so sieht die Aufrufliste aus:
$$$00001() line 79 _AfxDispatchCmdMsg(CCmdTarget * 0x00054538 {CMenue hWnd=0x000e057e}, unsigned int 1009, int 0, void (void)* 0x004020d1 CMenue::OnApi(void), void * 0x00000000, unsigned int 12, AFX_CMDHANDLERINFO * 0x00000000) line 88 CCmdTarget::OnCmdMsg(unsigned int 1009, int 0, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 302 + 39 bytes CDialog::OnCmdMsg(unsigned int 1009, int 0, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 97 + 24 bytes CWnd::OnCommand(unsigned int 1009, long 591228) line 2099 CWnd::OnWndMsg(unsigned int 273, unsigned int 1009, long 591228, long * 0x0005412c) line 1608 + 28 bytes CWnd::WindowProc(unsigned int 273, unsigned int 1009, long 591228) line 1596 + 30 bytes AfxCallWndProc(CWnd * 0x00054538 {CMenue hWnd=0x000e057e}, HWND__ * 0x000e057e, unsigned int 273, unsigned int 1009, long 591228) line 215 + 26 bytes AfxWndProc(HWND__ * 0x000e057e, unsigned int 273, unsigned int 1009, long 591228) line 379 AfxWndProcBase(HWND__ * 0x000e057e, unsigned int 273, unsigned int 1009, long 591228) line 220 + 21 bytes USER32! 77e727cd() USER32! 77e7334c() USER32! 77e8eea3() USER32! 77e8c5ea() USER32! 77e71416()
d.h. das ist der Zeitpunkt, nachdem der Stack Overflow geschehen ist, und ich eine Meldung bekomme:
Nicht abgefangene Ausnahme in API.exe: 0xC0000005: Access Violation.
...aber ich erkläre das am Besten Schritt für Schritt, was ich damit meine.
Also ich habe 2 Dialogklassen in meiner Anwendung, die jetzt für dieses Problem wichtig sind. Achja, und eine *App-Klasse von Typ CWinApp.
Diese Klasse, sie heisst CAPIApp, ruft meine erste Dialogklasse auf. Es wird eine ganz normaler modaler Dialog erstellt.
Die erste Dialogklasse heisst CMenue:
Der Header sieht wie folgt aus:#if !defined(AFX_MENUE_H__DDE39864_8706_4624_8E27_B263FC151DB3__INCLUDED_) #define AFX_MENUE_H__DDE39864_8706_4624_8E27_B263FC151DB3__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // Menue.h : Header-Datei // ///////////////////////////////////////////////////////////////////////////// // Dialogfeld CMenue #include "DBAnbindung.h" class CMenue : public CDialog { // Konstruktion public: CMenue(CWnd* pParent = NULL); // Standardkonstruktor //CMenue(ISaGsaRpConnection rPConnection, CDBAnbindung dBConnection, CString* ,CString* ,CString* ,CString* ,CString*, CString*, long, long, long, long, CString, int, CString, CString, CString, CString, CString, CString, CString, CWnd* pParent=NULL); CMenue(CDBAnbindung dBConnection, ISaGsaRpConnection rPConnection, CWnd* pParent=NULL); // Konstruktor mit Connect-Objekt ISaGsaRpConnection GetRpConnectionObject(); void SetRpConnectionObject(ISaGsaRpConnection rPObject); CDBAnbindung GetDBConnectionObject(); void SetDBConnectionObject(CDBAnbindung dBObject); ... public: ISaGsaRpConnection rPConnection; CDBAnbindung dBConnection; ...
Diese Klasse ruft eine Funktion auf, die den zweiten Dialog aufruft, nämlich den Dialog mit dem Namen Anmeldung. Der Aufruf ist auch modal:
void CMenue::OnApi() { if (rPConnection.IsConnected()){ rPConnection.Disconnect(); } CDialog::OnOK(); Anmeldung api; api.DoModal(); }
Der Header der Anmeldung-Klasse ist wie folgt:
#if !defined(AFX_ANMELDUNG1_H__F0F45E00_CD6F_4371_8C5E_C5A1FF2C7495__INCLUDED_) #define AFX_ANMELDUNG1_H__F0F45E00_CD6F_4371_8C5E_C5A1FF2C7495__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // Anmeldung1.h : Header-Datei // ///////////////////////////////////////////////////////////////////////////// // Dialogfeld Anmeldung #include "AppsUser.h" class Anmeldung : public CDialog { // Konstruktion public: Anmeldung(CWnd* pParent = NULL); // Standardkonstruktor // Anmeldung(CDBAnbindung dBAnbindung, ISaGsaRpConnection rPConnection, CWnd* pParent = NULL); // Standardkonstruktor mit RpConnection-Object ISaGsaRpConnection GetRpConnectionObject(); void SetRpConnectionObject(ISaGsaRpConnection rPObject); CDBAnbindung GetDBConnectionObject(); void SetDBConnectionObject(CDBAnbindung dBObject); ... public: CDBAnbindung m_DBAnbindung; CAppsUser m_AppsUser; ...
Dann wird aus dem zweiten Dialog wieder der erste aufgerufen
void Anmeldung::OnNaechsteSeite() { if (rPConnection.IsConnected()) { CDialog::OnOK(); CMenue dUI(Anmeldung::GetDBConnectionObject(), Anmeldung::GetRpConnectionObject()); dUI.DoModal(); }else{ CDialog::OnOK(); CMenue dUI; dUI.DoModal(); } UpdateData(false); }
...der Stack Overflow tritt erst dann auf, wenn ich versuche das zweite Mal aus dem ersten Dialog in den zweiten Dialog zu wechseln. Beim ersten Mal klappt alles Prima...
Habe null Ahnung warum, darum will ich erstmal den Stack vergrössern und sehen, was passiert
-
Ist das wirklich der gesamte Callstack? Beinhaltet eine der Klassen ein großes Array?
Du solltest wirklich dein Design überdenken. CMenue erstellt eine Instanz von Anmeldung, Anmeldung erstellt wieder eine Instanz von CMenue, und immer so weiter. Wenn du das oft genug machst, wird dir jeder noch so große Stack zu klein.
-
ja, zu beachten ist ja auch, dass das CMenue mein Hauptmenü darstellt und Anmeldung ein Unterdialog, der vom Hauptmenüe aufgerufen wird.
...in CMenue hab ich mehrere Buttons, die je nachdem verschiedene Dialogklassen aufrufen. Die Klasse Anmeldung ist dafür da, um ein Connect auf eine Datenbank zu erreichen. Ich drücke also im Hauptmenü auf den Button Connect, so wird die Dialogklasse Anmeldung aufgerufen und nachdem der Connect erfogt ist, wird der Dialog Anmeldung geschlossen und wieder das Hauptmenü aufgerufen, von wo aus ich weiter arbeiten kann. aber möchte ich ein zweites Mal die Dialogklasse(Druck auf Connect-Button) aufrufen, bricht mir das Pgm ab...
...ach ja, was ich noch fragen wollte...ich hab jetzt in der Klasse CMenue in der Funktion OnApi, wo der zweite Dialog aufgerufen wird, ein breakpoint gesetzt, beim ersten Aufruf hält mir das Pgm an dieser Stelle an, jedoch beim zweiten versuch komm ich garnet soweit, der Abbruch erfolgt schon irgendwo davor...
was wird denn noch alles bei einem Buttondruck gemacht, ausser der Nachrichtaustauschmethode...
...nach dem Abbruch krieg ich nur noch den Assembler-Code zu sehen:
--- intel\chkstk.asm ----------------------------------------------------------------- _chkstk: 004467E0 push ecx 004467E1 cmp eax,1000h 004467E6 lea ecx,[esp+8] 004467EA jb lastpage (00446800) probepages: 004467EC sub ecx,1000h 004467F2 sub eax,1000h 004467F7 test dword ptr [ecx],eax
//hier zeigt der Zeiger hin
..anscheinend prüft er da den Stack und es kommt zum Abbruch...
-
chullain schrieb:
ja,
Ist das die Antwort auf meine Frage, ob das wirklich der ganze Callstack ist, oder auf die Frage, ob du große Arraymember hast?
zu beachten ist ja auch, dass das CMenue mein Hauptmenü darstellt und Anmeldung ein Unterdialog, der vom Hauptmenüe aufgerufen wird.
Dann darf Anmeldung keine neue Instanz des Hauptmenüs erstellen! Du musst in CMenue::OnApi auf die Eingaben in Anmeldung reagieren (nach DoModal), nicht einfach in Anmeldung::OnNaechsteSeite eine zweite CMenue-Instanz erzeugen.
-
MFK schrieb:
Ist das die Antwort auf meine Frage...
sorry, ja, das ist der ganze CallStack, mehr war da nicht...
...also das Pgm stammt eigentlich nicht von mir...ich hab es halt überarbeitet und soll es jetzt erweitern...ok, nachdem ich mir den Header durchgeguckt habe, habe ich viele Arrays gefunden, die einfach nicht mehr gebraucht werden...nachdem ich die gelöscht habe, habe ich es nochmal laufen lassen, der Fehler ist aber immernoch da...und immernoch Stack Overflow......ich werde dann mal probieren aus dem CMenue auf den Dialog zu reagieren...
...wünscht mir Glück
-
hab jetzt folgendes versucht:
Anmeldung api; if (api.DoModal()==IDOK) { CMenue::SetRpConnectionObject(api.GetRpConnectionObject()); CMenue::SetDBConnectionObject(api.GetDBConnectionObject()); api.OnClose(); }
Die Methode OnClose():
void Anmeldung::OnClose() { CDialog::OnOK(); }
...jedoch, nachdem ich auf dem Dialog "Anmeldung" auf den Button mit der IDOK drücke, geht das Pgm in die Methode OnClose, dort in CDialog::OnOK und wieder in dieser Methode:
void CDialog::OnOK() { if (!UpdateData(TRUE)) { TRACE0("UpdateData failed during dialog termination.\n");
...auf UpdateData(TRUE), jedoch bricht er bei ASSERT(::IsWindow(...) ab...
BOOL CWnd::UpdateData(BOOL bSaveAndValidate) { ASSERT(::IsWindow(m_hWnd)); // calling UpdateData before DoModal? CDataExchange dx(this, bSaveAndValidate);
-
Und immer wieder sehe ich das es nicht einfach ist anderen Code zu verstehen beziehungsweise den Ansatz nachvollziehen zu können.
Anmeldung api; if (api.DoModal()==IDOK) { api.OnClose(); }
Das ist sinnlos da der Dialog geschlossen wurde.
Wenn du eine Hauptdielog hast dann rufe von diesem deine anderen Dialoge auf.
Nicht in einem Unterdialog wieder den Hauptdialog und dann solche Hacks wie "Schließe jetzt endlich den Dialog mit OnClose()".
-
Ok, das ist echt schon peinlich...haste Recht
Danke, es haut hin....jetzt klappt das Spitze...
-