Forum: PC-Programmierung Speicher alokieren


von Hansi (Gast)


Lesenswert?

Hallo Zusammen,

würde gerne erfahren, wie ich Speicher in C++ allokieren kann?

Ich habe fertige Klassen, die in einer Bibkliothek implementiert sind.

Hier das Problem:

KlasseSHAPE XYZ(KlasseSHAPE aShape1, KlasseSHAPE aShape2)
{
  KlasseCMP aCMP= KlasseCMP (aShape1, aShape2);
        aCMP.Build();
  return aCMP.Shape();

}

Der Absturz passiert bei größeren Dateien bei Klasse "KlasseCMP".

Wie kann ich hier am einfachsten Speicher allokieren, also bevor ich 
diese Zeile ausführe:

KlasseCMP aCMP= KlasseCMP (aShape1, aShape2);

?

von Peter II (Gast)


Lesenswert?

mit den paar infos kann niemand etwas anfangen. Kann es sein das dir der 
Stack ausgeht? Welche Fehlermeldung bekommt du genau? Was sind größere 
Dateien. Was passiert im Konstruktur von KlasseCMP?

von Vlad T. (vlad_tepesch)


Lesenswert?

Bitte such dir ein Buch oder Tutorial zum Thema C++.
Hier mangelt es offensichtlich an den absoluten Basics.

von Karl H. (kbuchegg)


Lesenswert?

Hansi schrieb:
> Hallo Zusammen,
>
> würde gerne erfahren, wie ich Speicher in C++ allokieren kann?

machst du doch schon.

> Wie kann ich hier am einfachsten Speicher allokieren, also bevor ich
> diese Zeile ausführe:
>
> KlasseCMP aCMP= KlasseCMP (aShape1, aShape2);

machs nicht so kompliziert.
1
KlasseSHAPE XYZ(KlasseSHAPE aShape1, KlasseSHAPE aShape2)
2
{
3
  KlasseCMP aCMP( aShape1, aShape2 );
4
  aCMP.Build();
5
  return aCMP.Shape();
6
}

Bist du sicher, dass du die KlasseSHAPE Objekte alle per Kopie übegeben 
willst?

von Hansi (Gast)


Lesenswert?

Wieso sollte ich diese nicht als Kopie übergeben?

ich bekomme die Fehlermeldung std::bad_alloc at memory location ...

von Karl H. (kbuchegg)


Lesenswert?

Hansi schrieb:
> Wieso sollte ich diese nicht als Kopie übergeben?

Ich weiß natürlich nicht, wie groß die Klassen sind.
Ich weiß auch nicht, was die CMP Klasse mit den ihm übergebenen Objekten 
macht.
Ich hab keine Ahnung, was mit der von der Funktion zurückgelieferten 
Kopie im Returnwert passiert.

Aber es ist ungewöhnlich, Objekte per Kopie zu übergeben.

> ich bekomme die Fehlermeldung std::bad_alloc at memory location ...

Dann musst du mal mehr zeigen.

von Hansi (Gast)


Lesenswert?

ich lese zwei Dateien ein, berechne mit der Funktion die Differenz und 
mit dem return-Wert mache ich nichtd weiter. Dieser wird an eine andere 
Funktion übergeben, die mir mein Ergebniss in eine Datei speichert., Der 
Fehler tritt aber bei der BErechnung auf, weil der Speicher anscheinend 
voll läuft ...

von Mark B. (markbrandis)


Lesenswert?

Hansi schrieb:
> Hallo Zusammen,
>
> würde gerne erfahren, wie ich Speicher in C++ allokieren kann?

Mit new. Und per delete wieder freigeben nicht vergessen.

Hat den Vorteil, dass das Objekt auf dem Heap auch dann noch existiert, 
wenn der aktuelle Scope verlassen wird.
Hat den Nachteil, dass man sich damit viele schöne Speicherlecks bauen 
kann. Das wird in der Entwicklung oft und gerne so gemacht ;-)

von Peter II (Gast)


Lesenswert?

Hansi schrieb:
> ich lese zwei Dateien ein, berechne mit der Funktion die Differenz und
> mit dem return-Wert mache ich nichtd weiter.

ich hoffe die lädst die Datein nicht komplett in den Speicher. Zeig uns 
mal die Stelle wo du etwas berechnest.

von Hansi (Gast)


Lesenswert?

Also.

Ich lade zwei Dateien mit folgendem Aufruf:
1
KlasseSHAPE aShape1 = readSTEP(argv[1]); 
2
KlasseSHAPE aShape2 = readSTEP(argv[2]);
Die Funktionen geben jeweils Ein Objekt (Shape) vom Typ "KlasseSHAPE" 
zurück.
Dieses Shape übergebe ich dann als Parameteter der Funktion:
1
KlasseSHAPE  aShapeRESULT = aCMP(aShape1, aShape2);

Das ist die Funktion, die ich oben angegeben habe. Bei der Berechnung 
der booleschen Differenz passiert der Absturz:
1
KlasseCMP aCMP = KlasseCMP (aShape1, aShape2);

Ich habe das jetzt so modifiziert, es funktioniert aber immer noch 
nicht:
1
KlasseCMP *aCMP ;
2
aCMP = new KlasseCMP(aShape1, aShape2);
3
aCMP->Build();
4
return aCMP->Shape();

von Peter II (Gast)


Lesenswert?

niemand weiss wie readSTEP arbeitet.

Eventuell könnte es schon reichen wenn du hier

KlasseCMP (aShape1, aShape2);

mit referenzen arbeiten würdest. Hier werden beide Objekte (vermutlich) 
nocheinmal auf den Stack kopiert.

Aber zeige doch mal alles, mit den codefetzen kann man nicht weiter 
helfen.

von Hansi (Gast)


Lesenswert?

Die eine FUnktion habe ich schon veröffentlicht, hier die readFUnktion:

1
KlasseShape readfile(char *filePath)
2
{
3
IGESControl_Reader myReader;
4
Standard_Integer nIgesFaces,nTransFaces;
5
myReader.ReadFile (filePath);
6
  
7
Handle(TColStd_HSequenceOfTransient) myList = KlasseShape.GiveList("faces");    
8
    nIgesFaces = myList->Length();
9
    nTransFaces = KlasseShape .TransferList(myList);
10
    cout<<"IGES Faces: "<<nIgesFaces<<" Transferred:"<<nTransFaces<<endl;
11
12
13
    return myReader.OneShape();  
14
}

Open CASCADE Bibliothek!

von Hansi (Gast)


Lesenswert?

readSTEP durch readfile ersetzt!

von Karl H. (kbuchegg)


Lesenswert?

Hansi schrieb:

> Ich habe das jetzt so modifiziert, es funktioniert aber immer noch
> nicht:
>
>
1
> KlasseCMP *aCMP ;
2
> aCMP = new KlasseCMP(aShape1, aShape2);
3
> aCMP->Build();
4
> return aCMP->Shape();
5
>


Natürlich nicht.
Das ist konzeptionell immer noch das gleiche wie
1
KlasseSHAPE XYZ(KlasseSHAPE aShape1, KlasseSHAPE aShape2)
2
{
3
  KlasseCMP aCMP( aShape1, aShape2 );
4
  aCMP.Build();
5
  return aCMP.Shape();
6
}

Ob du das Objekt lokal erzeugst, oder ob du es mittels new aus der Taufe 
hebst, ändert ja nichts am Objekt.
Das einzige was du getan hast ... du hast dir mit deinem new ein schönes 
Speicherloch (Memory Leak) eingefangen. Aber mehr hast du nicht getan 
bzw. verändert.

Du bellst den falschen Baum an.
Da musst du tiefer einsteigen: Wo genau passiert der Fehler? Wie sieht 
die Umgebung an dieser Stelle aus? Was war an dieser Stelle die Absicht 
im Code? Sind die Shape-Geometrien in Ordnung? etc.

Der Fehler mag sogar banal sein, aber ihm auf die Spur zu kommen ist es 
nicht. So wie in allen komplexen Systemen.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz Buchegger schrieb:

> Der Fehler mag sogar banal sein, aber ihm auf die Spur zu kommen ist es
> nicht. So wie in allen komplexen Systemen.

Und sinnvollerweise fängt man erst mal von vorne an.
d.h. hier
1
KlasseSHAPE aShape1 = readSTEP(argv[1]); 
2
KlasseSHAPE aShape2 = readSTEP(argv[2]);

Diese beiden Shapes lässt man sich mal wo ausgeben und sieht sich an, ob 
die korrekt eingelesen wurden.
Dazu lädt man dann natürlich nicht das CAD_Modell vom Eifelturm in das 
Programm mit 2einhalb Millionen Faces, sondern erst mal ganz einfache 
Körper: Würfel, Tetraeder.

von Mark B. (markbrandis)


Lesenswert?

Mir persönlich fehlt da schon mal die Fehlerbehandlung, denn in argv[1] 
und argv[2] kann ja auch kompletter Unsinn oder auch gar nichts 
drinstehen.

Oder etwas vermeintlich Sinnvolles, wie der Name einer zwar vorhandenen 
Datei, die aber riesengroß ist und das bei leider zu knappem (oder zu 
knapp konfiguriertem) Speicher auf dem Zielsystem.

von Karl H. (kbuchegg)


Lesenswert?

Mark Brandis schrieb:
> Mir persönlich fehlt da schon mal die Fehlerbehandlung, denn in argv[1]
> und argv[2] kann ja auch kompletter Unsinn oder auch gar nichts
> drinstehen.


Darüber hatte ich auch schon einen Post fertig. Über das Nichtbehandeln 
von Fehlercode, die die ReadFile Methode vom myReader garantiert 
zurückgibt.

Ich hab dann allerdings gesehen, dass er sich mit

   cout<<"IGES Faces: "<<nIgesFaces<<" Transferred:"<<nTransFaces<<endl;

da die Konvertierungsstatistik ausgeben lässt und daher gehe ich mal 
davon aus, dass ihm das aufgefallen wäre, wenn da überall 0 steht.


> wie der Name einer zwar vorhandenen Datei, die aber riesengroß ist

Das ist leider oft der Fall, dass Neulinge in einem komplexen System 
gleich mal die komplexeste Geometrie reinstopfen, die sie finden können, 
anstelle erst mal mit kleinen überschaubaren Geometrien erste Versuche 
zu fahren und sich langsam an all die kleinen Fallen ranzutasten, die 
einem in der CAD Geometrie erwarten.

von Mark B. (markbrandis)


Lesenswert?

Karl Heinz Buchegger schrieb:
> und sich langsam an all die kleinen Fallen ranzutasten, die
> einem in der CAD Geometrie erwarten.

Dein Spezialgebiet? :-)

von Hansi (Gast)


Lesenswert?

Also zum einen werden die Dateien richtig eingelesen. Die Tests habe ich 
bereits mit zahlreichen Modelle versucht, die aber kleiner waren: 
Würfel, Zylinder, Flaschendeckel, etc. - alle "Solids"

Die Modelle wurden korrekt eingelesen. Die großen Modelle habe ich 
natürlich auch eingelesen und auch ausgegeben. Hat alles einwandfrei 
funktioniert. Sicherlich ist der Speicheraufwand bei booleschen 
Operationen bei B-Reps sehr hoch, aber es muss doch auch eine Lösung 
geben oder aber  es ist so wie es ist ...

von Hansi (Gast)


Lesenswert?

Ach und was die Geometriene angeht, so speichert mit Catia V5 derzeit 
meine IGEs files nicht als solid ab. Daher verwendet ich die Modelle, 
die mir bereits zur Verfügung stehen.

Ich habe beispielsweise eine Quader erstellt, dem Flächen, falls nötig, 
zugeordnet, diese miteinander verbunden und das Ganze miteinander 
verknüpft. Aber das Modell wird als Flächenmodell gespeichert (gelbe 
FLächenfarbe) und nicht als Solud (graue Flächenfarbe) .. nur so am 
Rande ...

von Rolf Magnus (Gast)


Lesenswert?

Hansi schrieb:
> Sicherlich ist der Speicheraufwand bei booleschen Operationen bei B-Reps
> sehr hoch, aber es muss doch auch eine Lösung geben

Dazu müßte man dann aber dort nachschauen und nicht an der Stelle, wo 
das nur aufgerufen wird.

von Hansi (Gast)


Lesenswert?

Leider kann ich dort nichts aendern. Ich habe aber gesehen, dass die 
Bibliothek auch Allocate Funktionen bereithaelt. Vielleicht finde ich da 
etwas nuetzliches. Dachte ich kann einfach auf die Adresse referenzieren 
und genuegend Speicher zuweisen

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.