Eine Frage zur Speicherverwaltung
-
Jaja schon klar
Aber ich analysiere JPG Dateien und muss da viel dynamisch erzeugen... leider... irgendwie bin ich da sehr großzügig mit dem Speicher, wenn das Programm läuft sind schnell 400MB voll... schon krass, weiß auch nicht genau wo es her kommt denn ich habe nun jedem new ein entsprechendes delete spendiert und immer noch keine Besserung.
-
TheGrudge schrieb:
Jaja schon klar :)...
Dann ist ja gut.

-
jedem array new musst du ein delete [] spendieren.
-
Simon2 schrieb:
Hi,
nur der Vollständigkeit halber: Es gibt auch in C++ automatische Speicherverwaltung !
Man muss Objekte nicht mit new anlegen ... und dann auch nicht explizit freigeben.Beispiel:
int main() { string s = "ein normaler String"; cout << s; return 0; }Kein new, kein delete und absolut speicherleckfrei.:D
Gruß,
Simon2.
Jupp. Lustigerweise gibt es sogar ein Keyword dafür, also das was "default" ist wenn man nicht "static" schreibt. Und zwar "auto" - eben wie in "automatic"
:int main() { auto string s = "ein normaler String"; cout << s; return 0; }
-
Nur eine Randbemerkung, die nicht direkt mit dem Speicher zu tun hat: In C++ verwaltest du mehr als nur Speicher (z.B. Dateihandles oder Datenbank-Lock's). Und nicht alle diese Ressourcen werden automatisch aufgeräumt, wenn sich dein Programm beendet. Sowas freizugeben ist die Aufgabe deiner Destruktoren - und die werden nicht aufgerufen, wenn das System seinen Speicher zurückfordert. (und wenn du Glück hast, werden die nichtmal bei einem Neustart des Systems freigegeben :D)
-
CStoll schrieb:
(und wenn du Glück hast, werden die nichtmal bei einem Neustart des Systems freigegeben :D)
Und wie gibt man diese dann frei, wenn dies der Fall sein sollte?
-
System neu installieren
Aber besser ist es da, die Daten gar nicht erst zu verlieren.(aber so hartnäckige Sperren sind meist auf Dateiebene angelegt (z.B. eine gesperrte DB-Tabelle) und können umgangen werden, indem du die betroffene Tabelle kopierst und dann das Original löschst)
-
TheGrudge schrieb:
Jaja schon klar
Aber ich analysiere JPG Dateien und muss da viel dynamisch erzeugen... leider... irgendwie bin ich da sehr großzügig mit dem Speicher, wenn das Programm läuft sind schnell 400MB voll... schon krass, weiß auch nicht genau wo es her kommt denn ich habe nun jedem new ein entsprechendes delete spendiert und immer noch keine Besserung.Hem, also new brauchst du eigentlich nur, wenn du polymorphische benutzen willst. Simon2 hat schon ein Bsp. gebracht, wo man ohne Polymorphie auskommt. Was machst du denn bei new? Bei JPG fällt mir so ein, das du wahrscheinlich einen oder mehrere Speicherbereiche reservierst? Aber selbst das kann man meistens ohne new erreichen, in dem man z.B. std::vector nimmt. Der kann schon viel Arbeit abnehmen und somit Fehler vermeiden.
Und wenn du trotzdem Polymorphy brauchst, dann solltest du dir vielleicht Smartpointer anschauen.
-
Also bis jetzt ist das alles noch viel simpler:
Ich durchsuche das Bild und speichere alle Pixel, die zu einem "Objekt" gehören, auf einem Stack, um sie danach getrennt nochmal zu analysieren.
Also pushe ich per new() immer eine Koordinatenstruktur auf den Stack... oder ist das total doof von mir?
-
TheGrudge schrieb:
Also bis jetzt ist das alles noch viel simpler:
Ich durchsuche das Bild und speichere alle Pixel, die zu einem "Objekt" gehören, auf einem Stack, um sie danach getrennt nochmal zu analysieren.
Also pushe ich per new() immer eine Koordinatenstruktur auf den Stack... oder ist das total doof von mir?warum mit new?
std::stack<point> mypoints; mypoints.push(point(47,11)); mypoints.push(point(08,15));kein new, keine Memoryleaks.
-
Wie gesagt ich komme von Python und kenne C++ noch nicht so gut, ich dachte immer wenn ich keine Variable zuweise (also dynamisch erstelle) dann muss ich new benutzen...
-
Und das ist der Denkfehler - bei Sprachen wie Java oder Python ist new allgegewärtig, bei C++ wird es eher sparsam verwendet (und häufig gekapselt hinter Hilfsklassen (Smart-Pointer etc), die sich darum kümmern, den einmal angeforderten Speicher auch wieder freizugeben).
-
Also lebt die Koordinate namenlos auf dem Stack, normalerweise wäre sie ja sofort wieder gelöscht worden, aber da sie in einem Container lebt, der noch benutzt wird, wird sie auch nicht gelöscht und kann abgefragt werden?
Wo macht denn dann new konkret Sinn?
-
Ja, die Koordinate lebt im Stack - und wird erst gelöscht, wenn du sie per pop() wieder rauswirfst (oder der Stack selber vernichtet wird).
new wird häufig in der internen Datenverwaltung von solchen Containerklassen verwendet - std::stack<> nutzt einen std::deque<>, um seine Elemente zu lagern, dieser wiederum holt sich per new den benötigten Speicher (und weiß auch selber, wann und wie er den Speicher freigeben muß). Und es kommt zum Einsatz, wenn du dich mit Polymorphie beschäftigst (ein Zeiger kann auf Objekte verschiedener Datentypen verweisen und entsprechend anders reagieren), aber bei letzterem mußt du die Zeiger auch sammeln und dich selbst um die Speicherfreigabe kümmern.
-
TheGrudge schrieb:
Wie gesagt ich komme von Python und kenne C++ noch nicht so gut, ich dachte immer wenn ich keine Variable zuweise (also dynamisch erstelle) dann muss ich new benutzen...
Bei C++ ist eigentlich alles eine Variable. Bsp.:
vooid foo(std::string s) // s ist eine Variable! { // mit s kann ich machen was ich will }Genau das gleiche ist bei std::vector oder std::stack usw. der Fall.
Ein Container hilft dir, Speicher zu verwalten. Übergib ihm einfach deine Variable/Objekt und er regelt intern alles für dich. Die Container reservieren intern alles mit new, das mußt du aber nicht sehen.
-
TheGrudge schrieb:
Also lebt die Koordinate namenlos auf dem Stack, ...
Hmmm vielleicht nur noch mal der Klarheit zuliebe: Es gibt (mindestens) ZWEI Bedeutungen von "auf dem Stack":
point p; // (1): Stackvariable std::stack<point> mypoints; // (2) Verwendung eines STL-Containers namens "stack"(2) kann in seiner Implementierung durchaus Objekte mit "new" auf dem "Heap" ablegen.
Zweitens: std::stack legt eine Kopie ab:
point p(1, 2); mypoints.push(p); p.x = 3; cout << mypoints.top(); // -> 1Merke: Bei C++ kann sich hinter einer Variable direkt ein Objekt verbergen und nicht nur eine "Referenz".
War vielleicht klar, aber "doppelt genäht ..."

Gruß,
Simon2.
-
Ich würde gerne meine Map umbauen und habe nun überlegt, einen Vector zu nehmen und damit die Koordinaten zu speichern.
Der Key der Map soll das Label sein (eine ID-Nummer), der Vector enthält nun die Koordinaten.
Jetzt scheine ich aber nur mit new arbeiten zu können, denn ich bekomme Compilerfehler wenn ich folgendes probiere:
typedef vector<int> iVector; typedef map<int,iVector> myMap; myMap m; if (m[1]) m[1].push_back(11); else m[1] = iVector;Vielleicht baue ich auch nur wieder Mist
Jedenfalls soll es so sein, das wenn kein Vector existiert, soll er angelegt werden, ansonsten ein push_back erfolgen.Diese Version funktioniert hingegen:
typedef vector<int> iVector; typedef map<int,iVector*> myMap; myMap m; if (m[1]) m[1]->push_back(11); else m[1] = new iVector;Wieso muss ich hier nun new nutzen? Das kapiere ich noch nicht, kann der vector nicht "anonym" in der map leben?
-
m[1] = iVector;Dir ist schon klar, das du hier einen Typ und keine Variable/Objekt hinzufügst?

typedef vector<int> iVector; // Typdefinition! Nix Variable!
-
Na ich dachte bei new bleibts ja auch weg und den Namen kann ich nachher eh nicht verwenden... och dieses Speicherzeugs macht mich noch fertig
aber irgendwann wird man auch das kapiert haben.
-