Tödliche Objekte
-
Hi everyone
Kurze, allgemeine Frage zu Objekten in C++: Bei mir im Code findet sich folgende Schelife:
for(int i = 0; i < iMtrNo; i++) { CIEC1107 ewbTmp = CIEC1107(); CLPMeter lpTmp = CLPMeter(); CEMeter emTmp = CEMeter(); ... lpTmp = CLPMeter(ewbTmp); ... emTmp = CEMeter(ewbTmp); ... }Die Objekte versuche ich deshalb im for-Loop zu deklarieren, da sie danach nicht mehr benötigt werden und vom Speicher entfernt werden sollen (iMtrNo kann nämlich ziemlich gross werden). Das Problem: So, in dieser Form, ergibt mein Programm einen Segmentation Fault. Daraus lässt sich allerdings nicht viel schliessen, denn das ist die einzige Fehlermeldung, die mein einfältiges Embedded OS überhaupt ausgeben kann.

Rufe ich das Ganze allerdings so auf:
CIEC1107 ewbTmp = CIEC1107(); CLPMeter lpTmp = CLPMeter(); CEMeter emTmp = CEMeter(); for(int i = 0; i < iMtrNo; i++) { ... lpTmp = CLPMeter(ewbTmp); ... emTmp = CEMeter(ewbTmp); ... }bleibt der Segmentation Fault vorerst einmal aus. Nach meinem Verständnis werden so allerdings die Referenzen von lpTmp und emTmp iMtrNo-mal neuen Objekten zugewiesen, ohne dass die alten freigegeben würden. Da sich diese For-Schleife zu allem Überfluss in meiner main-Endlosschleife befindet, finde ich das natürlich schade.

Warum gibt der erste Code also einen Fehler? Und wie sorge ich dafür, dass der Speicher entsprechend wieder frei gegeben wird?

Thx für eure Hilfe und Greeetz
Kessi
-
Tach.
Das sind keine Referenzen, sondern Stackobjekte die Du da erzeugst. Du kannst in C++ Referenzen auf Objekte erzeugen, aber das ist etwas anderes. Im ersten Fall erzeugst Du pro Schleifendurchlauf fünf Stackobjekte. Im zweiten Fall erzeugst Du pro Schleifendurchlauf jeweils nur zwei Objekte auf dem Stack.
Da Du in einem Nebensatz Embedded OS erwähnst (kleiner Tipp für die zukunft, Compiler, Betriebssystem etc sind Informationen die durchaus interessat sind) gehe ich mal davon aus das der Stack dort relativ klein ist. Mein erster Tip wäre daher, daß im ersten Fall der Stack nicht groß genug ist um 5 Objekte aufzunehmen.
PS: Aus Neugierde, hast Du vorher Java geprogged?
-
Hm. Versuch mal rauszufinden wo es denn schnalzt. Dazu verwendet man normalerweise nen Debugger, aber einfache Ausgaben (printf) tuns auch. Wenn auch das nicht geht weil du keinen Schirm o.ä. hast musst du halt irgendwie anders Infos verschicken, über ne Serielle oder sonstwas. Zu wissen wo inetwa etwas passiert hilft meistens ungemein

-
schue schrieb:
PS: Aus Neugierde, hast Du vorher Java geprogged?
Aha, das merkt man scheinbar von weitem, eh
? Allerdings bin ich schon eine ganze Weile an einem C++ Projekt auf unserem MOXA 7408 embedded computer beteiligt. Ein embedded computer ist das Ding allerdings nur seiner Form und seinem Betriebssystem wegen (Montavista embedded Linux 4.18). Hardwaremässig verfügt er nämlich z.B. über 128MB RAM und eine 266er CPU.schue schrieb:
Tach.
Das sind keine Referenzen, sondern Stackobjekte die Du da erzeugst. Du kannst in C++ Referenzen auf Objekte erzeugen, aber das ist etwas anderes. Im ersten Fall erzeugst Du pro Schleifendurchlauf fünf Stackobjekte. Im zweiten Fall erzeugst Du pro Schleifendurchlauf jeweils nur zwei Objekte auf dem Stack.Tja, mein Fehler. Als Ex-Java-Programmierer schuldig im Sinne der Anklage, wo meines Wisens Objekte nur als Referenzen repräsentiert werden. Die Frage bleibt allerdings: Dass mein Stack mit fünf Objekten vollläuft, glaube ich nicht (besonders nicht bei solchen von meinen eigenen Klassen, die sollten wirklich minimen Speicher verbrauchen). Ebenfalls frage ich mich, was mit dem alten Objekt passiert, wenn ich
lpTmp = CLPMeter(ewbTmp);aufrufe. In Java wird lpTmp, welche nur eine Referenz auf ein Objekt ist, überschrieben mit einer Referenz auf das neu erzeugte Objekt. Das alte Objekt bleibt im Speicher bestehen, weshalb der GarbageCollector einspringen muss. So einen gibt es in C++ allerdings nicht, wenn ich mich nicht irre, weshalb ich fürchte, Speicherplatz ins Nirvana zu senden
.hustbaer schrieb:
Hm. Versuch mal rauszufinden wo es denn schnalzt.
Nun, eine eingehende printf-Analyse
zeigt, dass der Segmentation Faultfor(int i = 0; i < iMtrNo; i++) { CIEC1107 ewbTmp = CIEC1107(); // genau hier, beim 2. Schleifendurchlauf auftreten muss, ... // ... da ein printf() an dieser Stelle nicht mehr ausgegeben wird. (Ein printf() genau vor obiger Anweisung wird noch angezeigt) CLPMeter lpTmp = CLPMeter(); CEMeter emTmp = CEMeter(); ... lpTmp = CLPMeter(ewbTmp); ... emTmp = CEMeter(ewbTmp); ... }Phew, soviel dazu also. Vielen Dank auf jeden Fall für euere Hilfe und greeetz
Kessi
-
[quote="KessiMC"]Ebenfalls frage ich mich, was mit dem alten Objekt passiert, wenn ich
lpTmp = CLPMeter(ewbTmp);aufrufe. [/cpp]
Das alte Objekt bleibt auf dem Stack bis der Scope verlassen wird (ende des for-blockes).
btw, mach mal ein sizeof von deinen Klassen und schau wie groß sie wirklich sind, dann informier Dich wie groß der Stack ist, das müßte einstellbar sein. Je nachdem was Dein Programm insgesamt macht kann der Stack durchaus an seine Grenze stossen.
ZUgegebn, da ich den Code nicht kenne rate ich hier nur.
Was meinen Java-guess angeht, ja, das mit den Referenzen hat Dich verraten
Anders als in Java hat C++ zwei unterschiedliche Arten von Speicher, den Stack und den Heap. Das, was den java-Referenzen am nähesten kommt wären heap-objekte die man mit new anlegt, also z.B. CEMeter* emTmp = new CEMeter(ewbTmp); der Heap ist quasi der Freispeicher. Wichtig, anders als bei Java muß man mit new angelegte Objekte auch explizit mit delete wieder löschen.Anders sind die Objekte ohne new, also CEMeter emTmp = CEMeter(ewbTmp); In dem fall wird ein Objekt auf dem Stack angelegt. Der Vorteil des Stacks ist, daß diese Objekte automatisch beim verlassen des Scope gelöscht werden. Der Stack hat aber eine Obergrenze, ist er voll, gibts nen stack overflow.
-
Aha, das war tatsächlich 'ne wichtige Info
. Wer weiss, eines Tages darf ich mich vielleicht ja doch noch endlich C-Programmierer nennen
.Auf jeden Fall besten Dank, ich werde gleich die Grösse meiner Objekte überprüfen und im Zweifelsfall versuchen, einige davon in den Heap auszulagern.
Schö'n Abend noch und greeetz
Kessi