Speicherleck nur beim "new"?
-
Hallo david.dda,
die Freigabe des Speichers bezieht sich aber auf eine evtl. Zuweisung von "op->data = static_cast<void *>(new X);". Gibt es auch solche (oder ähnliche) Speicherallokationen?
Aber wie schon geschrieben, ist das keine gute Implementierung, anscheinend nur ein Notbehelf, um Speicherlecks zu fixen...
Edit: und auch sehr fehleranfällig, falls z.B. konstante Zuweisungen á laop->data = (void *)42; // oder op->data = (void *)"hello";passieren (habe extra mal kein static_cast benutzt, um zu zeigen, was alles so programmiert werden könnte...)
-
danke, es stimmt, es wurde eine Allokation erstellt, die dann mit dem vergessenen delete statement nachträglich korrigiert wurde (es wurde also der reservierte Speicher an dem op->data zeigt, gelöscht - in diesem Fall der Speicher an dem "conndata" zeigt - ):
t_connectiondata_changeuser *conndata = new t_connectiondata_changeuser; t_connop *op = new t_connop; op->data = conndata; op->op = USERCONTROL_CONNOP_CHANGEUSER; op->userid = m_userid; conndata->user = m_status.user; m_pOwner->SendNotification(FSM_CONNECTIONDATA, (LPARAM)op); return TRUE; }*conndata ist ein Struct:
struct t_connectiondata_changeuser { CStdString user; };nun kann ich aber nicht rausfinden, wo auch der Speicher an dem *op zeigt gelöscht wurde. Es sieht so aus, als würde dieser nicht deallokiert.
Mein Source code analyzer meldet folgendes:
*Memory Leak
(Code Quality, Control flow)The function SendTransferinfoNotification() in ControlSocket.cpp allocates memory on line 2847 and fails to free it.*
Line 2847 enthält folgendes Code: t_connop *op = new t_connop;
-
david.dda schrieb:
nun kann ich aber nicht rausfinden, wo auch der Speicher an dem *op zeigt gelöscht wurde. Es sieht so aus, als würde dieser nicht deallokiert.
Auch, wenn Du das als Frage formuliert hättest, kann man Dir hier nicht helfen, weil wir "Dein Analyse-Tool" nicht kennen und keinen Überblick über das Programm haben, was Du analysierst. Du anscheinend auch nicht.
david.dda schrieb:
Mein Source code analyzer
Ja welcher ist dass denn nun?!
david.dda schrieb:
meldet folgendes:
*Memory Leak
(Code Quality, Control flow)The function SendTransferinfoNotification() in ControlSocket.cpp allocates memory on line 2847 and fails to free it.*
Line 2847 enthält folgendes Code: t_connop *op = new t_connop;
Tja, und nun? Was soll uns das sagen? Schau mal in der Dokumentation zu dem von Dir nicht näher spezifizierten Tool nach, wie so eine Meldung zu bewerten ist. Der Satz "The function..." ist sicherlich richtig. Aber das allein garantiert Dir noch kein Memory-Leak. Es könnte also ein flascher Alarm sein. Es könnte aber auch richtig sein, weil das Tool nirgends wo ein "
delete p" gefunden hat, wobei p ein Ausdruck vom Typt_connop*ist. Dann würde ich auch ein Speicherleck melden, allerdings nicht mit so einem blöden "The function..."-Text. Das ist nämlich so nichtssagend. Natürlich muss man nicht immer in derselben Funktion den Speicher freigeben, den man angefordert hat. Im Gegenteil. Der Freispeicher ist gerade dazu da, Objekte anzulegen, die eine längere Lebensdauer haben und nach verlassen einer Funktion nicht sofort wieder zerstört werden, so wie es bei automatischen Objekten der Fall wäre.Gruß,
SP
-
ich habe den Code von FileZillaServer mit 5 Source Code Analysatoren durchgelaufen. CppCheck und RATS - beide sind nicht kommerzielle Werkzeuge und finden nur offensichtliche Fehler, wie Gebrauch von gefährlichen C++ Funktionen (strcpy..) dann habe ich C++Test verwendet - dieses Tool läßt sich super konfigurieren und ist sehr übersichtlich, PC-Lint - da habe ich noch Schwierigkeiten bei der Konfig. und Fortify - von dem auch die Fehlermeldung stamm, Fortify ist einfach zu installieren, leicht in der Benutzung und hat viele Features (Summary, Recommendations, Diagram, Details...) für die Fehlermeldungen. Allerdigs konnte keines von diesen Tools den Memory leak über den wir die ganze Zeit sprechen finden.
-
david.dda schrieb:
Allerdigs konnte keines von diesen Tools den Memory leak [...] finden.
Warum wundert Dich das?
-
also hälst Du nicht viel von diesen Tools?
Es sind statische Source Code Analysatoren, dynamische würden den leak vielleicht finden, aber die habe ich nicht ausprobiert. Ich weiß auch nicht wie die einzelnen Tools den Quellcode analysieren. In der Dokumentation zu diesen gibt es zwar einige Beispiele, diese sind aber eher ziemlich kurz und einfach, damit man so ungefähr weiß, wie ein memory leak.. im Quellcode gefunden wird:Consider the example: char *p, *q = 0; p = malloc(10); p = q; // Warning -- memory leak We are able to issue a Warning because the return from malloc has an allocation flag that indicated that the returned value points to a freshly allocated region that is not going to be freed by itself.
-
david.dda schrieb:
Ich habe schon einige Bücher über C++ gelesen, aber weil es nur viel Theorie ohne Praxis war, versteht man vieles nicht so eindeutig.
Eigendlich ist es doch genau umgekehrt: Man kann die Praxis nur verstehen wenn man vorher die Theorie begriffen hat. Ansonsten läuft man Gefahr die Praxis nicht zu verstehen, sondern zu interpretieren, wodurch beliebig falsche Denkmodelle entstehen können, wie wir an diesem Beispiel zum Verhalten von Zeigern ja sehr schön beobachten konnten...
Technisch gesehen ist die Regel für Speicherverwaltung einfach: Jedes new muß durch ein passendes delete wieder freigegeben werden. Das wars auch schon. Memory-leaks entstehen immer dann, wenn diese Regel gebrochen wird.
david.dda schrieb:
ich habe den Code von FileZillaServer mit 5 Source Code Analysatoren durchgelaufen.
Code Analysator != Memory-leak detector. Du benutzt also die falschen Tools und kannst daher auch nix finden.
Das ist ungefähr so als würdest Du einen Schraubenzieher benutzen um einen Baum zu fällen... Und Dich dann wundern warum das nicht so richtig funktioniert...
-
loks schrieb:
david.dda schrieb:
Ich habe schon einige Bücher über C++ gelesen, aber weil es nur viel Theorie ohne Praxis war, versteht man vieles nicht so eindeutig.
Eigendlich ist es doch genau umgekehrt: Man kann die Praxis nur verstehen wenn man vorher die Theorie begriffen hat. Ansonsten läuft man Gefahr die Praxis nicht zu verstehen, sondern zu interpretieren, wodurch beliebig falsche Denkmodelle entstehen können, wie wir an diesem Beispiel zum Verhalten von Zeigern ja sehr schön beobachten konnten...
Dann wird es sicher besser, wenn er noch 10 Bücher liest, aber nix programmiert.

-
loks schrieb:
david.dda schrieb:
Ich habe schon einige Bücher über C++ gelesen, aber weil es nur viel Theorie ohne Praxis war, versteht man vieles nicht so eindeutig.
Eigendlich ist es doch genau umgekehrt: Man kann die Praxis nur verstehen wenn man vorher die Theorie begriffen hat. Ansonsten läuft man Gefahr die Praxis nicht zu verstehen, sondern zu interpretieren, wodurch beliebig falsche Denkmodelle entstehen können, wie wir an diesem Beispiel zum Verhalten von Zeigern ja sehr schön beobachten konnten...
Manchmal wird einem aber die Theorie schlecht erläutert, und dann hilft nur noch Praxis. Ich habe in meinen C++-Anfängen (vorher intensiv Basic und Assembler) über Klasse und Polymorphie nichts verstanden. Weil das Buch einfach die Theorie und Beispiele schlecht herüber brachte. Erst durch intensive Praxis (intensive Arbeit an einem beruflichen C++ Projekt) ging mir wirklich von einem Moment auf den anderen ein Geistesblitz durch den Kopf. Danach konnte ich mein Wissen wieder durch Theorie weiter entwickeln.
-
Artchi schrieb:
Manchmal wird einem aber die Theorie schlecht erläutert, und dann hilft nur noch Praxis. Ich habe in meinen C++-Anfängen (vorher intensiv Basic und Assembler) über Klasse und Polymorphie nichts verstanden. Weil das Buch einfach die Theorie und Beispiele schlecht herüber brachte. Erst durch intensive Praxis (intensive Arbeit an einem beruflichen C++ Projekt) ging mir wirklich von einem Moment auf den anderen ein Geistesblitz durch den Kopf. Danach konnte ich mein Wissen wieder durch Theorie weiter entwickeln.
Dem stimme ich voll zu und ich denke, dass das auch sehr viele tun werden.
Das zeichnet sich imo dadurch aus, dass bei uns an der UNI Programmierung das wahrscheinlich Praxisorientierteste Fach von allen ist. Die Prüfung besteht hauptsächlich aus angewandten Beispielen und man muss da wirklich Code hin schreiben, anstatt irgendwelche Theoriefragen beantworten, die man einfach auswendig lernen könnte.