PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : delete vs. delete[] bei C-Arrays und kaputter Smartpointer im Vector


mekakic
2008-09-19, 14:28:09
Hi

ich schaue mir gerade Code an, der in einen RefCounting Smart-Pointer einen C-Array (von Int8s) packt. Der SmartPointer soll dann eigentlich den Besitz über diesen Speicherbereich übernehmen, aber der weiß dann nur noch von einem Pointer und dem ersten Speicherbereich des Arrays - das heißt beim finalen release() ruft er auf dem gekapselten Pointer nur ein delete statt eines delete[] auf.

Welchen Unterschied hat dies für das Verhalten des Programms? Im Debugger betrachtet scheint dies trotzdem "irgendwie" zu funktionieren.

Allerdings knallt es, wenn diese Elemente in einem std::vector sind beim Zugriff. Unabhängig davon, daß dies wohl nicht richtig ist, frage ich mich wo hier der Unterschied ist? Wenn ich mir den Ablauf im Debugger anschaue, funktioniert es wenn die SmartPointer nicht im vector gespeichert werden trotzdem, im Vector knallt es dann. Hat jemand einen Plan, wo hier der Unterschied liegt?

Trap
2008-09-19, 14:45:48
new+delete[] oder new[]+delete sind beides undefiniertes Verhalten. Ich hab mir nie die Mühe gemacht herauszufinden was genau wie schief läuft wenn man das benutzt. Das würde sowieso vom Compiler+Compilerversion abhängen...

Vielleicht legt new[] an der Adresse direkt vor dem zurückgegebenen Pointer Daten ab und delete[] benutzt die dann. Wenn da aber keine Daten liegen passiert irgendwas falsches.

Xmas
2008-09-19, 15:38:38
Häufig ist der einzige Unterschied dass delete [] den Destruktor für alle Arrayelemente aufruft, während delete nur das erste Array-Element beachtet.

Ob ein Smartpointer in Container-Typen funktioniert hängt von der Implementierung ab. std::auto_ptr ist beispielsweise für std::vector ungeeignet.

Gast
2008-09-19, 16:09:37
in solchen momenten bin ich wirklich froh dass es Java etc.gibt :D

Coda
2008-09-19, 16:28:28
Kannst du den Smart-Pointer nicht durch sein Array-Äquivalent ersetzen?

Gauß
2008-09-22, 01:17:32
in solchen momenten bin ich wirklich froh dass es Java etc.gibt :DIch musste echt laut lachen als ich in OpenOffice bei Textverarbeitung warten musste bis eine 3 Ghz CPU ein zehn-Seiten Dokument Formateinstellungen gaendert hat.
Bitte nenne jetzt keine Links zu Leistungstests irgendwelcher Professoren!

Zum Thema: nutzt du scoped_array/shared_ptr von Boost?

Coda
2008-09-22, 01:40:20
Ich musste echt laut lachen als ich in OpenOffice bei Textverarbeitung warten musste bis eine 3 Ghz CPU ein zehn-Seiten Dokument Formateinstellungen gaendert hat.
OpenOffice ist C++.

Gauß
2008-09-22, 01:48:31
OpenOffice ist C++.Und warum musste ich dann fuer den Letter Wizard die Java Laufzeitumgebung aktualisieren? :rolleyes:

Coda
2008-09-22, 01:52:40
OpenOffice läuft auch ohne Java. Das ist ein Fakt. Kannst du in den Optionen ausschalten.

Java wird soweit ich weiß nur für Automatisierungszeugs eingesetzt.

Gauß
2008-09-22, 16:04:13
Ich habe sehr genau hingeschaut wo, wieviel CPU-Zeit verbraucht wurde, da ich den Code modifizierte, und es war eindeutig der Java code vom Letter Wizard der da eine halbe Ewigkeit fuer triviale Aufgaben benoetigte.

Und das ist ja auch nur eines von immens vielen Beispielen wo bewiesen wird dass in vielen (wenn nicht den meisten) Faellen eine automatische Speicherverwaltung in der Praxis extrem ineffizient ist.

Xmas
2008-09-22, 22:29:35
Und das ist ja auch nur eines von immens vielen Beispielen wo bewiesen wird dass in vielen (wenn nicht den meisten) Faellen eine automatische Speicherverwaltung in der Praxis extrem ineffizient ist.
Wie kommst du darauf dass hier die Speicherverwaltung die Ursache wäre?

Coda
2008-09-22, 23:35:29
Hab ich mich auch gefragt. Vor allem ist das allozieren mit einem GC eigentlich sehr viel schneller, nur das wieder freigeben kann halt Leistung brauchen.

Gauß
2008-09-23, 16:42:33
Wie kommst du darauf dass hier die Speicherverwaltung die Ursache wäre?Weil das typischer Weise bei nicht extrem seriell-rechenintensiven Anwendungen mit Abstand das groesste Effizienzproblem ist.

Ich habe vor einer ganzen Weile, als ich noch mit Java rummurksen musste, direkt gemessen wie extrem die JVM bei vielen Programmen prinzipbedingt zu fuerchterlicher Heapfragmentierung neigt.
Das schlimme ist dass ja gerade die Leute, die sich mittels Java der Speicherverwaltung weitgehend entziehen wollen, sich nahezu Null Kopf um diese Probleme machen.

Xmas
2008-09-23, 16:59:08
Weil das typischer Weise bei nicht extrem seriell-rechenintensiven Anwendungen mit Abstand das groesste Effizienzproblem ist.
Wie Coda schon sagte, allozieren ist mit einem GC sehr schnell. Den Preis bezahlt man bei der Collection, welche im Normalfall nur sporadisch ausgeführt werden sollte. Ist vielleicht der Heap zu klein?

Ich habe vor einer ganzen Weile, als ich noch mit Java rummurksen musste, direkt gemessen wie extrem die JVM bei vielen Programmen prinzipbedingt zu fuerchterlicher Heapfragmentierung neigt.
Inwiefern soll das prinzipbedingt sein? Zudem ist ein Compacting GC eine effiziente Lösung für Heapfragmentierung.

Das schlimme ist dass ja gerade die Leute, die sich mittels Java der Speicherverwaltung weitgehend entziehen wollen, sich nahezu Null Kopf um diese Probleme machen.
Es stimmt natürlich, dass man sich auch mit GC immer noch Gedanken um die Speicherverwaltung machen muss.

Gauß
2008-09-23, 18:15:30
Das prinzipbedingte Problem eines GC ist das Defizit eines oertlichen und zeitlichen Kontexts.

Was ich auf die Schnelle ueber "Compacting GC" gefunden habe, deutet lediglich auf den Versuch die Aufgaben des Heap API des Betriebsystems besser zu handhaben.

Coda
2008-09-23, 19:10:05
Nein, ein Compacting GC kann auch Elemente verschieben, da er alle Referenzen darauf kennt. Damit kann er den Heap defragmentieren.

Xmas
2008-09-23, 20:16:57
Das prinzipbedingte Problem eines GC ist das Defizit eines oertlichen und zeitlichen Kontexts.
Mir ist nicht ganz klar wie dies zu besonders starker Heapfragmentierung führen soll.

Trap
2008-09-23, 20:32:11
Man kann auch mit Java manuelles Speichermanagement machen. Pro Typ mit eigenem Heap:
typeX myheap = new typeX[10000];
typeX newX() {...};
void deleteX(typeX toDelete){...};

In den allermeisten Fällen ist das aber grober Unfug :tongue:

robobimbo
2008-09-23, 22:42:21
Ich denke auch, das GC mehr nutzt als kostet.

Performancekritisch wirds meist dann, wenn sehr viele Objekte Instanziert werde, wieder gelöscht, wieder instanziert - klar wird dann die GC da auch mal Hand anlegen.

Aber durch gewissenhafte Optimierung (Objectpools) lassen sich auch diese Ecken umschiffen, und es überwiegen bei weiten die Vorteile.

Trap
2008-09-23, 23:08:38
Es wäre in Java ganz sinnvoll ein Interface anzubieten, mit dem man dem GC zusätzliche Informationen geben kann, bzw. bestimmte Parameter des GC festlegen kann.

Ein paar mögliche Funktionen kann man in der Doku zu Lispworks finden:
http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-166.htm (nur ein Teil davon haben mit dem GC zu tun)