Frage zu einem Programmabsturz
-
Also erst mal .... Das ist mein Programm ...
Hab alle Sachen ,die der Debugger gemeldet hat aus der Welt geschafft und es dann compiliert . Das Ergebnis davon ist ,dass ich ein Proramm geschaffen hab ,das - ganz toller Weise - nur abstürzen kann.#include <iostream> #include <cstdlib> #include <cstdio> using namespace std; int IDN = 0; int Zufallszahl (unsigned int max = 100, unsigned int start = 0 ) { srand( time(NULL) ); int zahl; zahl = (rand()% max )+ start; return zahl; } class pwsegment { public: pwsegment() { IDNo = IDN++; IDN = IDNo; int stelle; for (stelle = 0 ;stelle < 136 ;stelle ++) { int stelles; Segment[stelles] = Zufallszahl (1000 , 100); stellecs++; } } int IDNo; int Segment[136]; }; int main (int argc, char *argv[]) { pwsegment a; int i; for (i = 0 ; i < 136 ;i++ ) { int stelleaus; cout << a.Segment[stelleaus]<< endl; stelleaus++; } system ("PAUSE"); return 0; }**Jetzt zu meinen Fragen . Liegt das erstens an meinem PC?
Oder hab ich irgendwas grundlegendes falsch gemacht ,was ein Debugger nicht erkennt ? Oder is das Programm einfach nur Müll?PS : Das Programm soll einem Array (Segment) in einem Objekt 136 Zahlen zuweisen und danach soll das alles ausgegeben werden . Nebenbei soll dem Objekt eine ID zugewiesen werden ....(aber das is nicht so wichtig)**
Danke für eure Hilfe

-
sam2005<< schrieb:
Oder is das Programm einfach nur Müll?[X]
Schau doch wenigstens mal die Compilerwarnungen an.
-
Ganz klar, du hast nen Hardwareschaden!
-
a) Du hast anscheined zuerst den Debugger, dann erst den Compiler verwendet ==> Du weisst gar nicht was die Beiden machen.
b) Ein Debugger erkennt gar nix, er zeigt dir nur Sachen an, und du kannst dann erkennen was nicht funktioniert.
c) Wie schon gesagt gibt die Compiler sicher einige Warnungen.
-
DAS Programm lässt sich kompilieren

Naja, los gehts:
int Zufallszahl (unsigned int max = 100, unsigned int start = 0 ) { srand( time(NULL) ); int zahl; zahl = (rand()% max )+ start; return zahl; }Tu das
srand( time(NULL) );da raus, das sollte nur einmal pro Durchlauf des GANZEN PROGRAMMS aufgerufen werden, also in main() oder so...
int stelle; for (stelle = 0 ;stelle < 136 ;stelle ++) { int stelles; Segment[stelles] = Zufallszahl (1000 , 100); stellecs++; } }das
int stelles;kann weg, wozu wird das denn gebraucht?
Dadurch stürtzt dein Programm nämlich auch ab:
int stelles;deklariert und definiert eine Variable, die du uninitialisiert verwendest, um das Array Segments[] zu indizieren. D.h. wenn stelles zufälligerweise größer ist also 135 schmiert dein Programm ab.
Die Zeile
stellecs++;ist übrigens der Grund, aus dem sich das Programm (eigentlich) gar nicht kompilieren lassen dürfte, stellecs gibt es ja gar nicht, sondern nur stelles...
Segment[stelles] = Zufallszahl (1000 , 100);muss dann natürlich
Segment[stelle] = Zufallszahl (1000 , 100);heißen.
Der ganze Block nochmal neu:
for(int stelle = 0; stelle < 136; ++stelle) { Segment[stelle] = Zufallszahl (1000 , 100); }Das hier
pwsegment() { IDNo = IDN++; IDN = IDNo;verstehe ich nicht ganz. Wieso erhöhst du IDN (was ja eigentlich sinnvoll ist), weist dann aber IDN wieder IDNo zu, also die unerhöhte Kopie? Ich würde IDN = IDNo einfach weglassen, wenn ich verstanden habe, was du machen willst.
Hier
int i; for (i = 0 ; i < 136 ;i++ ) { int stelleaus; cout << a.Segment[stelleaus]<< endl; stelleaus++; }Hast du fast das gleiche Problem wie oben auch, du musst i benutzen, um das Array zu indizieren und nicht stelleaus, das wieder eine uninitialisierte Variable ist. Das
stelleaus++;bewirkt auch nichts, da stelleaus beim nächsten Schleifendurchlauf sowieso wieder (mit einem zufälligen Wert) neu erzeugt wird.
Hoffe, ich konnte helfen.
Felix :xmas2:
EDIT: Das mit dem Unterschied zwischen einem Debugger und einem Compiler stimmt allerdings...
Die Einrückung des Codes würde ich übrigens auch nochmal überdenken (ist zwar besser als gar nicht eingerückt, aber trotzdem) und der Knopf C/C++ ist besser für C/C++ Code geeignet als einfach der Code Button.
Die (unregistrierten) Trolle da würde ich übrigens nicht sosehr beachten, jeder fängt mal an

-
Yo vielen Dank hat mir auf jeden Fall geholfen ....
wollt nur mal fragen ob du bei Gelegenheit erklären könntest ,was der Vorteil davon ist zuerst zu inkrementieren !
Aber THXPS.
IDNo = IDN++;
IDN = IDNo; // <- das lag daran ,dass ich da vorher nen zeiger hatte und das schnell geändert hab.
-
Die Zuweisung ist unnötig.
IDNo = IDN++;Denn schon das erhöht die Variable
IDN++;PreIncreament ist schneller, da es keine Kopie erstellen muss,
allerdings optimieren Compiler das afaik i. d. Regel wegDazu gibt glaub ich nen Beitrag in den FAQ
-
bei primitiven typen optimieren das fast alle compiler weg, wenn möglich. nur bei selbst definierten typen nicht.
-
Jetzt mal ne andere Frage:
Kann ich eigentlich keinen Postincreament machen, wenn der Copy-Konstruktor
nicht erreichbar ist?
-
*push*
-
PreIncreament schrieb:
Jetzt mal ne andere Frage:
Kann ich eigentlich keinen Postincreament machen, wenn der Copy-Konstruktor
nicht erreichbar ist?-
Bei eingebauten Typen stellt sich die Frage nicht, da alle Operatoren public sind.
-
Der Postincrement Operator muss als Returnwert ja nicht eine Instanz der Klasse haben, der kann ja irgendwas zurückgeben. Wenn der Postincrement Operator nun z.B. void zurückliefert stellt sich die Frage auch nicht, da keine Beziehung zum Copy-Ctor mehr besteht.
-
Der MSVC (mit "language extension" AUSgeschaltet natürlich) erlaubt in dem Fall zumindest den Aufruf des Postincrement Operators, aber nicht die Initialisierung eines anderen Objektes mit dem Returnwert. Ist auch irgendwie logisch, wenn man den Returnwert bloss verwirft muss ja nirgends der Copy-Ctor von ausserhalb der Klasse aufgerufen werden. Von daher schätze ich dass es auch laut Standard OK sein wird.
class A { public: A() { } private: A(A const&) { } public: A operator ++ (int) { return *this; } A foo() { return *this; } }; int main() { A a; a++; // OK a.foo(); // OK // A a2 = a++; // Fehler // A a3 = a.foo(); // Fehler }
-