0xC0000005: Access Violation beim Beenden des Programs
-
Hallo Zusammen,
bei dem folgenden Proggy bekomme ich, die oben genannte, Fehlermeldung. Alle Zeilen werden ausgefuehrt, bis einschliesslich zur letzten printf...Ist ein typisches und sehr einfaches C-Proggy (win32-Konsolenanwendung, geschrieben mit Visual C++ 6.0), darum nervt der Fehler auch echt total, aber ich checks einfach nicht...
Hat da jmd. ne Idee, wo der Fehler liegt?!
// ----------------------- Proggy Listing -------------------
#include <stdio.h>
#define NAMELEN 30
struct pkw
{
char name[NAMELEN];
float geschw;
short leist;
short zylinder;
};void main (void)
{
struct pkw wagen;printf("\n\nBitte geben sie einen Namen ein [max %d]: ", NAMELEN);
scanf ("%s", wagen.name);printf("\nBitte geben sie die Geschwindigkeit ein: ");
scanf ("%g", &wagen.geschw);printf("\nBitte geben sie die Leistung an: ");
scanf ("%d", &wagen.leist);printf("\nBitte geben sie die Anzahl der Zylinder ein: ");
scanf ("%d", &wagen.zylinder);printf("\nName : %s", wagen.name);
printf("\nGeschw.: %g", wagen.geschw);
printf("\nLeist. : %d", wagen.leist);
printf("\nZylin. : %d", wagen.zylinder);
}// ---------------------- End Listing ----------------------
Beim Debug des Fehlers (file: CRT0.c)
#ifdef WPRFLAG
__winitenv = _wenviron;
mainret = wmain(__argc, __wargv, _wenviron);
#else /* WPRFLAG */
__initenv = _environ;
mainret = main(__argc, __argv, _environ); <---- Hinweis hier 1
#endif / WPRFLAG */*1) __wargv 0x00000000
CXX0030: Fehler: Ausdruck kann nicht ausgewertet werden
... das gleiche bei:
__winitenv 0x00000000
_wenviron 0x00000000
-
Vermutlich liegt es daran, dass du mit %d in short zu lesen versuchst und dir damit den Stack zerhaust. Versuch's mit
scanf("%hd", &&wagen.leist);und entsprechend für zylinder.
Ansonsten ist
void main(void)ein Fehler; main muss laut ANSI-Standard int zurückgeben. Richtig wäre
int main(void) { ... return 0; }(Rückgabe 0 bedeutet per Konvention "Ohne Fehler durchgelaufen").
-
Hallo Seldon!
Danke fuer die schnelle Antwort.
Hab Deine Tipps eben mal durchprobiert und erfolg gehabt!!
// ------------- Problem geloest! --------------
Aber etwas, was mir aufgefallen ist:
Arbeite geraede eines dieser Lehrbuecher durch und bei allen Programme vorher, hat der Compiler nie wegen
void main (void) {}gemeckert. Du hast aber natuerlich recht, dass der Funktionsaufruf norm. mit
intausgefuehrt wird.
Das scheint aber nicht die Loesung gewesen zu sein. Vielmehr hat Dein kleines "h" beim Formatkennzeichner geholfen... Leider kenn ich den nicht; nur das "l" bei long, double Variablen. Magste mir vllt. noch ein paar Worte zu diesem "h" sagen, bzw. warum ich damit den Stack zerhacke?!
Noch ein kleiner Hinweis: Bei Deinem Tipp mit der scanf haste 2 "&&" benutzt... da hat der Compiler gemeckert. Hab weiterhin nur 1 benutzt und es funzt.
Auf jedenfall "Danke" fuer die Hilfe!
-
Nachtrag:
Scheint auch ohne 'h' (hab's gefunden!), aber dafuer mit 'int' Variablen zu gehen

-
Das ist richtig. h ist in diesem Zusammenhang ein Modifikator für scanf-Formatspezifikatoren, die Ganzzahlformate beschreiben (d.h. d, u, x etc.) und bedeutet, dass der entsprechende short-Typ verwendet wird. %d liest in int, %hd in short int. %u liest in unsigned int, %hu in unsiged short int usw. Entsprechend geht das mit %ld und %lu für long int und unsigned long int respektive.
Um die nächste Frage gleich abzufangen: Es gibt keinen Unterschied zwischen short und short int. short ist lediglich eine kürzere Schreibweise für short int, und gleiches gilt für long, unsigned, unsigned short und unsigned long.
Wenn dein Lehrbuch tatsächlich "void main" benutzt, ist es aller Wahrscheinlichkeit nach sehr alt; man hat diese Dinge in vergangenen Dekaden deutlich laxer gesehen. Es gab aber immer Systeme, unter denen es nicht funktioniert hat, und es gibt wirklich keinen Grund, sich verwundbar für solchen Ärger zu machen.
-
seldon schrieb:
Um die nächste Frage gleich abzufangen: Es gibt keinen Unterschied zwischen short und short int. short ist lediglich eine kürzere Schreibweise für short int, und gleiches gilt für long, unsigned, unsigned short und unsigned long.
Und noch ein Nachtrag: Das gilt nicht für char, singed char und unsigned char! So wirklich merken tut man das in C normalerweise nicht, aber in C++ wird der Unterschied wichtig.
-
So, hab noch ein bischen rumprobiert... und ja, lag wohl 100% an dem Formatkennszeichner.
Hab dann mal
sizeof()auf die Datentypen angewandt und herausgefunden dass
short2Byte,
int&
longje 4 Byte gross sind. Was wohl der Grund dafuer sein duerfte, dass ich %hd fuer
shortnutzen sollte / muss ^^
Und noch am Rande: Jo, das Buch ist von '98... aber es hat schon den Hinweis, dass man
printf()ja auch immer mit Rueckgabewert nutzen sollte; nur um zu sehen, ob alles seine Richtigkeit hat und der Vollstaendigkeitshalber. Werde es mir fuer
main()auch angewoehnen.
Und danke fuer die Hinweise bezueglich der andern Datentypen, bzw. dem Unterschied zu C++. Duerfte mir dann in ein paar Wochen/Monaten einen neuen Eintrag, hier im Forum, ersparen

Weiter so Leute, Ihr habt mir echt geholfen! (Y)
-
intkann auch 2 Byte groß sein. Evtl. geht dein Buch davon aus.Für den Wertebereich gilt: short <= int <= long.
Darum musst du bei short und long (und den Typen aus stdint.h) den Formatkennzeichner mit angeben.
Hat jemand schonmal einen Compiler mit
sizeof(int) = 3gesehen?
-
Die Breiten von short, int und long bei dir sind mehr oder weniger zufällig so, wie sie sind. Vom Standard garantiert ist lediglich
1. short fasst Werte mindestens zwischen -215 und 215 - 1
2. int fasst Werte mindestens zwischen -215 und 215 - 1
3. long fasst Werte mindestens zwischen -231 und 231 - 1
4. long long fasst Werte mindestens zwischen -263 und 263 - 1
5. sizeof(long long) >= sizeof(long) >= sizeof(int) >= sizeof(short)Die Wertbereiche für unsigned foo sind entsprechend zwischen 0 und mindestens 2n mit n = 16, 32 bzw. 64, wobei unsigned short so breit ist wie short, unsigned int do breit wie int usw.
Bei mir ist beispielsweise sizeof(long) == 8, und es ist davon auszugehen, dass irgendwann 128-Bit-long longs üblich werden.
-
Thomas Bock schrieb:
(win32-Konsolenanwendung, geschrieben mit Visual C++ 6.0)
Diese Compilerversion läuft wie auch andere standardmäßig im Featuremodus, erlaubt also irgendwelche Compilererweiterungen. Mit /Za kann man ihn zu ANSI C überreden, wobei der Standard nicht festlegt, ob und welche Warnungen ein standardkonformer Compiler erzeugen muss (void main und das ganze unsinnige Zeug...).
- du leerst den Tastaturpuffer nicht (probiere mal, eine Zahleneingabe vor die Stringeingabe zu platzieren)
- du machst keine Längenprüfung bei der Stringeingabe
- du machst keine Über/Unterlaufsprüfung bei den Zahleneingaben
- gib als <name> mal "Alfa Romeo" ein und schaue dir das Ergebnis an
- ...