Statische Code Analyse, Intel Tool findet Memory leak in xmemory
-
Hi Leute,
ich habe gerade mal die Intel tools zur statischen Code Analyse auf meinem Projekt angewandt (benutze auch Intel Compiler).
Ich selbst verwerde kein einziges mal new oder delete, ich benutzte immer std::vector.
Intels tool hat nun zwei "kritsiche" Fehler gefunden, die angebelich ein Memory Leak verursachen koennen.
Ich bin totaler Anfaenger, das Tool zeigt auf folgenden Code:
(die Zeile wo "operator new" aufgerufen wird. Ist das wirklich ein Memory Leak oder liegt das Tool da falsch?28 template<class _Ty> inline 29 _Ty _FARQ *_Allocate(_SIZT _Count, _Ty _FARQ *) 30 { // allocate storage for _Count elements of type _Ty 31 void *_Ptr = 0; 32 33 if (_Count <= 0) 34 _Count = 0; 35 else if (((_SIZT)(-1) / sizeof (_Ty) < _Count) 36 || (_Ptr = ::operator new(_Count * sizeof (_Ty))) == 0) 37 _THROW_NCEE(bad_alloc, 0); 38 39 return ((_Ty _FARQ *)_Ptr); 40 }
mfg
-
Da ist ja reiner Assembler noch übersichtlich dagegen.
-
Das sieht mir wie ein Wrapper um new aus. Das ist an sich erstmal nicht falsch, solange es richtig benutzt wird. Aus der reinen Anwesenheit dieses Codes kann ein Programm aber nichts folgern. Hast du wirklich eine statische Codeanalyse gemacht? Ich kann mir vorstellen, dass dieser Code zur Laufzeit als "Ursache" eines Lecks gefunden wird (wobei er aber nicht schuldig wäre, sondern der fehlerhafte Nutzercode), aber nicht bei einer statischen Analyse.
-
Ich stimme zu, es gibt kein direktes memory leak in dieser Funktion. Obwohl die Funktion etwas seltsam wirkt.
Zunächst wird _SIZT als vorzeichenbehafteter Typ behandelt
if (_Count <= 0) _Count = 0;
wird aber direkt danach wie ein vorzeichenloser Type genutzt, um einen Maximalwert zu erhalten
((_SIZT)(-1) / sizeof (_Ty) < _Count)
Dann wird der Rückgabewert von operator new geprüft
(_Ptr = ::operator new(_Count * sizeof (_Ty))) == 0
Was wenig Sinn macht, da operator new(std::size_t) niemals null zurückgibt.
Trotzdem sollte der eigentliche Fehler, falls existent, woanders liegen
-
kryptisch schrieb:
Da ist ja reiner Assembler noch übersichtlich dagegen.
Zwischenfrage: Warum ist der Code der misten Standardbiliotheken so cryptisch und unleserlich?
Ich meine, so ein STL (der M$-Stevie da, den meine ich) muss den Code doch auch schreiben und verstehen...
-
Skym0sh0 schrieb:
kryptisch schrieb:
Da ist ja reiner Assembler noch übersichtlich dagegen.
Zwischenfrage: Warum ist der Code der misten Standardbiliotheken so cryptisch und unleserlich?
Ich glaube, der erste Schritt ist die Namenskonvention, dass alles mit Unterstrich und Großbuchstaben losgeht. Aber das ist eben so vorgegeben, da können sie schlecht was dagegen machen.
-
Ich wollte dieselbe Frage stellen, dann kam mir der Gedanke, dass sie selbst bei nicht-öffentlichen Symbolen diese Namenswahl treffen müssen, damit die Bibliothek nicht von User-Makros abgeschossen werden kann.
-
Skym0sh0 schrieb:
Zwischenfrage: Warum ist der Code der meisten Standardbiliotheken so cryptisch und unleserlich?
Ich meine, so ein STL (der M$-Stevie da, den meine ich) muss den Code doch auch schreiben und verstehen...Der User darf ja fast alles mit #define ersetzen und wenn die Standardlibrary zufällig die gleichen Bezeichner verwendet, würde es Murks geben. Bezeichner, die mit _ und danach Großbuchstabe oder mit __ beginnen, sind im Standard für reserviert worden.
Außerdem gibt es noch etliche Spezialfälle, z.B. als explicit deklarierte Kopierkonstruktoren. Man kann die Objekte nicht schön übersichtlich mit = kopieren, sondern muss die Klammernschreibweise verwenden.
Sie STL ist auch sehr optimiert, z.B. wird für std::copy mit pointern und trivially constructible auf memmove oder memcpy umgeleitet und damit nicht alles etliche Male kopiert werden muss, findet sich eine große Anzahl seltsamer Funktionen und Klassen dort.
-
Eine statische Analyse scheint es nicht wirklich zu sein. So heisst aber jedenfalls der Menupunkt im Visual Studio mit dem Intel Tool. Das Tool zeigt eine Aufrufesequenz die zu dem Memory Leak tool fuehren soll. Aber ist egal. An meinem Code kann es auf jeden fall nicht liegen da kein new.
-
MickyMouse schrieb:
An meinem Code kann es auf jeden fall nicht liegen da kein new.
Es wird dir doch die komplette Aufrufsequenz gezeigt, dann weißt du doch, wer schuld ist.