Discussion:
Einschraenkungen in WM_INITDIALOG ?
(zu alt für eine Antwort)
ha
2015-08-22 18:54:48 UTC
Permalink
Hallo

Ich stehe vor einem Rätsel. Und zwar öffne ich einen
Dialog, wobei ich in WM_INITDIALOG Ram per malloc
beschaffe. Das ist sehr wenig: ca. 1.5 MByte.

Das Programm stürzt nach Start bald ab. Reduziere ich die
Grösse um den Faktor 10, läuft alles tadellos.

Compiliere ich das Programm mit Debuginformationen,
läuft es auch tadellos ! So kann ich es leider auch
nicht debuggen, weil es nur im Release-Modus abstürzt.

Darf man in WM_INITDIALOG noch nicht "allzuviel" Ram anfordern?

Und der Debugmodus umgeht diese mögliche Beschränkung?

Meine Debug- und Release-Settings sind identisch.


Systemdaten: Win7 Ultimate 64 Bit
VisualStudioExpress 2013 , Sprache C
Olaf Schmitt
2015-08-22 19:14:12 UTC
Permalink
Post by ha
Hallo
Ich stehe vor einem Rätsel. Und zwar öffne ich einen
Dialog, wobei ich in WM_INITDIALOG Ram per malloc
beschaffe. Das ist sehr wenig: ca. 1.5 MByte.
Das Programm stürzt nach Start bald ab. Reduziere ich die
Grösse um den Faktor 10, läuft alles tadellos.
Compiliere ich das Programm mit Debuginformationen,
läuft es auch tadellos ! So kann ich es leider auch
nicht debuggen, weil es nur im Release-Modus abstürzt.
Darf man in WM_INITDIALOG noch nicht "allzuviel" Ram anfordern?
Und der Debugmodus umgeht diese mögliche Beschränkung?
Meine Debug- und Release-Settings sind identisch.
Systemdaten: Win7 Ultimate 64 Bit
VisualStudioExpress 2013 , Sprache C
Linker default stack size könnte es sein:
https://msdn.microsoft.com/en-us/library/8cxs58a6.aspx

Da der Debugger eigenen Stack braucht, wird er das wohl wesentlich höher
setzen.


Olaf
ha
2015-08-22 19:31:55 UTC
Permalink
Post by Olaf Schmitt
https://msdn.microsoft.com/en-us/library/8cxs58a6.aspx
Da der Debugger eigenen Stack braucht, wird er das wohl wesentlich höher
setzen.
Danke ! Hat geholfen :-)

Was mir aber noch nicht klar ist: Spielt WM_INITDIALOG
eine besondere Rolle? Denn ich hole mir innerhalb
von Funktionen regelmäßig wesentlich mehr Ram, als in
diesem Fall. Bislang nur zufällig nicht während
WM_INITDIALOG.

Reserviere ich mir Ram auf diese Weise: char ram[hier ein Betrag]
würde ich das Problem verstehen.

Aber ich dachte, malloc ist vom Stack unabhängig.
Olaf Schmitt
2015-08-22 19:46:25 UTC
Permalink
Post by ha
Post by Olaf Schmitt
https://msdn.microsoft.com/en-us/library/8cxs58a6.aspx
Da der Debugger eigenen Stack braucht, wird er das wohl wesentlich höher
setzen.
Danke ! Hat geholfen :-)
Was mir aber noch nicht klar ist: Spielt WM_INITDIALOG
eine besondere Rolle? Denn ich hole mir innerhalb
von Funktionen regelmäßig wesentlich mehr Ram, als in
diesem Fall. Bislang nur zufällig nicht während
WM_INITDIALOG.
Reserviere ich mir Ram auf diese Weise: char ram[hier ein Betrag]
würde ich das Problem verstehen.
Aber ich dachte, malloc ist vom Stack unabhängig.
Malloc legt AUF dem Stack seine Daten ab.
Dazu subtrahiert er vom jetzigen Stack den Wert von malloc.
Und bei deinem Limit von 1MB liegt die Anfangsdresse dessen, was malloc
zurück gibt, in irgendeinem Bereich, wo er nichts zu suchen hat.


Bei char[100000000] weiß der Compiler, dass er den Stack um diesen Wert
beim Linker erhöhen muss, bei malloc weiß er es nicht, da der Compiler
kein Hellseher ist.




Olaf
ha
2015-08-22 20:13:12 UTC
Permalink
Post by Olaf Schmitt
Post by ha
Aber ich dachte, malloc ist vom Stack unabhängig.
Malloc legt AUF dem Stack seine Daten ab.
Ich hatte mich undeutlich ausgedrückt. Ich dachte, die
Verwendung von malloc passt den Stack automatisch an.
während feste Vorgaben wie char x[1000] evtl. eine
Linkeroption erfordern.

Wie auch immer: Leider funktioniert es immer noch nicht.
Nachdem ich den Stackwert von Hand setzte, lief es einmal.
Und danach wieder nicht. Setze ich den Wert extrem hoch,
ernte ich beim Start des Programms:

Die Anwendung konnte nicht korrekt gestartet werden (0xc0000017)
Olaf Schmitt
2015-08-22 20:48:36 UTC
Permalink
Post by ha
Post by Olaf Schmitt
Post by ha
Aber ich dachte, malloc ist vom Stack unabhängig.
Malloc legt AUF dem Stack seine Daten ab.
Ich hatte mich undeutlich ausgedrückt. Ich dachte, die
Verwendung von malloc passt den Stack automatisch an.
während feste Vorgaben wie char x[1000] evtl. eine
Linkeroption erfordern.
Wie auch immer: Leider funktioniert es immer noch nicht.
Nachdem ich den Stackwert von Hand setzte, lief es einmal.
Und danach wieder nicht. Setze ich den Wert extrem hoch,
Die Anwendung konnte nicht korrekt gestartet werden (0xc0000017)
Irgend etwas machst du falsch.
Poste mal den Code.


Olaf
ha
2015-08-22 21:13:16 UTC
Permalink
Irgend etwas machst du falsch. Poste mal den Code.
Im folgenden das wesentliche und vereinfacht.
Die tatsächliche Struktur ist 148 Bytes gross.
Ich allokiere Ram für 10000 dieser Strukturen nach
unten stehendem Muster.

Das Ganze lief noch, als die Struktur um 4 LONGs kleiner
war. Nach Erweiterung um 4 LONGs gab es das Problem.
Reserviere ich Ram für weniger Strukturen, läuft es tadellos.

Ich hatte noch nie Probleme, per malloc Ram anzufordern. Auch
nicht bei grösseren Mengen. Daher stehe ich hier wirklich vor
einem Rätsel.


------------------- cut -------------------



struct BeispielS {
LONG x, y, z;
};


struct BeispielS *ARRAY_P;
int groesse;



Und in der Dialog-Funktion geht es so weiter:

case WM_INITDIALOG:

// Von diesem Wert hängt es ab: Absturz oder ok.
groesse = 10000;

if (!(ARRAY_P =
(struct BeispielS *)malloc(groesse * (sizeof(struct BeispielS )))))
{
// Fehlerbehandlung
return FALSE;
}

... usw.



Den if/malloc-Block schreibe ich hier so, um Zeilenumbruchproblemen
vorzubeugen.
ha
2015-08-22 21:15:51 UTC
Permalink
Ich vergaß zu erwähnen, das ich statt der
Berechnung im malloc-Aufruf auch den festen
Wert direkt eintragen kann: Gleiche Wirkung.
Ein "integer-Überlauf" ist also nicht die Ursache.
Olaf Schmitt
2015-08-23 03:24:07 UTC
Permalink
Post by ha
Irgend etwas machst du falsch. Poste mal den Code.
Im folgenden das wesentliche und vereinfacht.
Die tatsächliche Struktur ist 148 Bytes gross.
Ich allokiere Ram für 10000 dieser Strukturen nach
unten stehendem Muster.
Das Ganze lief noch, als die Struktur um 4 LONGs kleiner
war. Nach Erweiterung um 4 LONGs gab es das Problem.
Reserviere ich Ram für weniger Strukturen, läuft es tadellos.
Ich hatte noch nie Probleme, per malloc Ram anzufordern. Auch
nicht bei grösseren Mengen. Daher stehe ich hier wirklich vor
einem Rätsel.
Gut.
Der Code sieht auf den ersten Blick unauffällig aus.

Welchen Compiler benutzt du?

Alternativ mal an der Heap Size rumschrauben.
Malloc benutzt den Heap. Hatte ich mit dem Stack durcheinander gebracht.
https://msdn.microsoft.com/en-us/library/f90ybzkh.aspx
Aber eigentlich sollte malloc dann auch null zurück geben, wenn da was
faul wäre.


Nur nebenbei....
Die Größe ist dynamisch? Oder stellst du die fest ein?
Bei fest, einen #define nemhen.
#define SIZE_BeispielS_ARRAY 10000


Und sonst siehst du dir mal diese Speicheranforderungssachen an:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366533%28v=vs.85%29.aspx
Post by ha
------------------- cut -------------------
struct BeispielS {
LONG x, y, z;
};
struct BeispielS *ARRAY_P;
int groesse;
// Von diesem Wert hängt es ab: Absturz oder ok.
groesse = 10000;
if (!(ARRAY_P =
(struct BeispielS *)malloc(groesse * (sizeof(struct BeispielS )))))
{
// Fehlerbehandlung
return FALSE;
}
... usw.
Den if/malloc-Block schreibe ich hier so, um Zeilenumbruchproblemen
vorzubeugen.
ha
2015-08-23 04:18:40 UTC
Permalink
Post by Olaf Schmitt
Irgend etwas machst du falsch.
Du lagst mit dieser Aussage richtig ;-)

Erstmal vielen Dank für deine Hilfe. Die Infos aus
deiner Antwort sind in jedem Fall interessant.

Aber hier war es wieder einmal ein Fehler der zufällig nicht
auffiel, weil sich das Drama innerhalb des Heap abspielte und
Windows keinen Grund zum Eingreifen hatte. Das mein Programm
keine fehlerhafte Arbeit ablieferte lag daran, das es in dem
Fall, den ich gleich beschreibe, an anderer Stelle den Vorgang
abbricht.


Ich greife, wie üblich, auf die Array-Elemente mittels einer
Index-Variable zu.
Die erhält ihren Wert von diversen Funktionen. Kann eine solche
Funktion situationsabhängig kein Resultat liefern, meldet sie das,
indem -1 zurückgegeben wird.

Weil ich manchmal ein Esel bin, der nicht genau hinsieht, habe ich
vor Einsatz nicht auf -1 geprüft und den Wert gleich als Index für
das Array genutzt.

Wie es aussieht, landet ein solcher Zugriff erst dann außerhalb des
Heap, wenn das Programm mehr als eine bestimmte Menge Ram angefordert
hat. Und erst dann lässt Windows das Programm "abstürzen".

Solange ich unterhalb dieser Grenze blieb, wurde zwar auf "verbotenen"
Speicher zugegriffen, der aber immer noch meinem Programm gehörte.

So wird man erstmal auf eine falsche Fährte geführt :-)
Olaf Schmitt
2015-08-23 06:50:47 UTC
Permalink
Post by ha
Post by Olaf Schmitt
Irgend etwas machst du falsch.
Du lagst mit dieser Aussage richtig ;-)
Erstmal vielen Dank für deine Hilfe. Die Infos aus
deiner Antwort sind in jedem Fall interessant.
Aber hier war es wieder einmal ein Fehler der zufällig nicht
auffiel, weil sich das Drama innerhalb des Heap abspielte und
Windows keinen Grund zum Eingreifen hatte. Das mein Programm
keine fehlerhafte Arbeit ablieferte lag daran, das es in dem
Fall, den ich gleich beschreibe, an anderer Stelle den Vorgang
abbricht.
Ich greife, wie üblich, auf die Array-Elemente mittels einer
Index-Variable zu.
Die erhält ihren Wert von diversen Funktionen. Kann eine solche
Funktion situationsabhängig kein Resultat liefern, meldet sie das,
indem -1 zurückgegeben wird.
Weil ich manchmal ein Esel bin, der nicht genau hinsieht, habe ich
vor Einsatz nicht auf -1 geprüft und den Wert gleich als Index für
das Array genutzt.
Irgendwie kenne ich das :-)
Post by ha
Wie es aussieht, landet ein solcher Zugriff erst dann außerhalb des
Heap, wenn das Programm mehr als eine bestimmte Menge Ram angefordert
hat. Und erst dann lässt Windows das Programm "abstürzen".
Solange ich unterhalb dieser Grenze blieb, wurde zwar auf "verbotenen"
Speicher zugegriffen, der aber immer noch meinem Programm gehörte.
So wird es gewesen sein.
Immerhin hast du jetzt genug Lektüre für malloc & Co :-)

Olaf
Stefan Reuther
2015-08-23 09:01:19 UTC
Permalink
Post by Olaf Schmitt
Post by ha
Aber ich dachte, malloc ist vom Stack unabhängig.
Malloc legt AUF dem Stack seine Daten ab.
Dazu subtrahiert er vom jetzigen Stack den Wert von malloc.
Und bei deinem Limit von 1MB liegt die Anfangsdresse dessen, was malloc
zurück gibt, in irgendeinem Bereich, wo er nichts zu suchen hat.
Nein. Das was du da beschreibst, ist alloca. malloc bedient sich vom
Heap und benötigt (bis auf die paar Bytes für den eigentlichen
Funktionsaufruf) keinen Stack.
Post by Olaf Schmitt
Bei char[100000000] weiß der Compiler, dass er den Stack um diesen Wert
beim Linker erhöhen muss, bei malloc weiß er es nicht, da der Compiler
kein Hellseher ist.
Welcher Compiler ist das? Der Compiler müsste dazu den kompletten
Aufrufgraphen des Programms kennen (von wo wird die Funktion aufgerufen?
Wird sie rekursiv aufgerufen?). Mir ist nicht bekannt, dass es überhaupt
die Möglichkeit gibt, diese Information in Objektdateien abzulegen.


Stefan
Olaf Schmitt
2015-08-23 10:10:03 UTC
Permalink
Post by Stefan Reuther
Post by Olaf Schmitt
Post by ha
Aber ich dachte, malloc ist vom Stack unabhängig.
Malloc legt AUF dem Stack seine Daten ab.
Dazu subtrahiert er vom jetzigen Stack den Wert von malloc.
Und bei deinem Limit von 1MB liegt die Anfangsdresse dessen, was malloc
zurück gibt, in irgendeinem Bereich, wo er nichts zu suchen hat.
Nein. Das was du da beschreibst, ist alloca. malloc bedient sich vom
Heap und benötigt (bis auf die paar Bytes für den eigentlichen
Funktionsaufruf) keinen Stack.
Post by Olaf Schmitt
Bei char[100000000] weiß der Compiler, dass er den Stack um diesen Wert
beim Linker erhöhen muss, bei malloc weiß er es nicht, da der Compiler
kein Hellseher ist.
Welcher Compiler ist das? Der Compiler müsste dazu den kompletten
Aufrufgraphen des Programms kennen (von wo wird die Funktion aufgerufen?
Wird sie rekursiv aufgerufen?). Mir ist nicht bekannt, dass es überhaupt
die Möglichkeit gibt, diese Information in Objektdateien abzulegen.
Stefan
Ich hatte Stack schon zu Heap korrigiert....eben Abend-Alzheimer :-)


Olaf

Loading...