new und delete von pointern
-
Hallo Leute, ich weiß nicht ob diese Frage hier oder ins C-Forum gehört. Da es
new/deletestattmalloc()/free()verwendet versuche ich erst einmal hier.Ich schaffe es nicht einen Memory Leak loszuwerden. Normalerweise arbeite ich nicht mit manueller Speicherverwaltung, bin jetzt aber durch eine externe Vorgabe dazu gezwungen worden. Mein Problem ist ein Memory Leak (laut Visual Leak Detektor) im
ptr_aden ich nicht loswerden kann. Das Programm hat dadurch einen völlig weltfremden fluss und landet beiconst bool tmp = false; if( tmp ) { // trotz false landet man hier }trotz
falseinnerhalb desifblocks. Scheint so als ob ich irgendwo über den zugelassenen Bereich schreibe..Wo ich den Fehler "vermute":
Ich habe die Funktionfunc_a()die ein Array aus einem Pointer erzeugt, der vom Sichtbarkeitsbereich weder zufunc_a()noch zufunc_b()gehört.float *ptr_a = NULL; void func_a( ... , &int size_a , float * &ptr_a ) { ... size_a = // Ergebnis vieler Berechnungen ptra = new float[size_a]; } void func_b( int size_a , float * &ptr_a ) { // ... nutze den Pointer A delete [] ptr_a; }Dieses Array wird in
func_b()gelöscht. Darf ich das, wenn diese wie in den Funktionssignaturen als Referenz übergeben werden oder muss ich es im selben Sichtbarkeitsbereich löschen wo es erzeugt wurde?Danke
-
const bool tmp = false; if( tmp ) { // trotz false landet man hier }Wenn ich mich nicht irre, dann dürften das die meisten neueren Compiler wegoptimieren.
-
ptra = new float[size_a];Wo kommt denn ptra her?
-
Sone schrieb:
const bool tmp = false; if( tmp ) { // trotz false landet man hier }Wenn ich mich nicht irre, dann dürften das die meisten neueren Compiler wegoptimieren.
Nicht im Debugmodus. Es nur ein Beispiel, dass es bei einem konstanten bool false im if Block landet, was an sich (mMn) für eine Speicherkorrumpierung spricht.
Sone schrieb:
float * &ptr_a )Willst du das wirklich so haben?
Sicherlich nicht!
Ich muss einen Pointer aus der höchsten Sichtbarkeitsebene an die Funktionen reichen und sehe im Moment keine andere Lösung.
Der Programmfluss ist so:
- Pointer wird in außerhalb von
func_a()erzeugt - und an
func_a()weitergegeben. - Darin wird die benötigte Größe ermittelt, der Speicher reserviert und das Array befüllt.
- Danach geht er aus
func_a()raus. - Aus dem obersten Sichtbarkeitsbereich wird der nun befüllte Pointer an
func_b()weitergegeben. - Darin wird er benutzt und deleted.
Wenn ich unmittelbar nach dem
deleteein Programmabbruch erzwinge, erhalte ich Memory Leaks. Wenn ich weitermache erhalte ich einen nicht nachvollziehbaren Programmfluss.
- Pointer wird in außerhalb von
-
asdasdasdasd schrieb:
Der Programmfluss ist so:
- Pointer wird in außerhalb von
func_a()erzeugt - und an
func_a()weitergegeben. - Darin wird die benötigte Größe ermittelt, der Speicher reserviert und das Array befüllt.
- Danach geht er aus
func_a()raus. - Aus dem obersten Sichtbarkeitsbereich wird der nun befüllte Pointer an
func_b()weitergegeben. - Darin wird er benutzt und deleted.
Wenn ich unmittelbar nach dem
deleteein Programmabbruch erzwinge, erhalte ich Memory Leaks. Wenn ich weitermache erhalte ich einen nicht nachvollziehbaren Programmfluss.Da scheint wohl irgendwo der Wurm drin zu sein.
Der Ablauf gibt nicht viel Raum für Memory Leaks, oder "nicht nachvollziehbaren Programmfluss.#include <cstddef> #include <cassert> void create(float*& p, std::size_t N){ p = new float[N]; } void destroy(float*& p, std::size_t){ delete [] p; p=0; } int main(){ float *p = 0; create(p, 50); assert(p!=0); destroy(p,50); assert(p==0); }Was sollte da passieren? Ausser bei:
3) ...wird befüllt...
und
6) ...wird benutzt...
- Pointer wird in außerhalb von
-
Furble Wurble schrieb:
...
Hmm... dann muss ich den Fehler woanders suchen... danke schonmal an alle.
-
Redesign mit einem modernen C++ Stil!
asdasdasdasd schrieb:
Ich schaffe es nicht einen Memory Leak loszuwerden.
Wenn Du C++ modern verwendet, ist die Leckgefahr verschwindend klein.
asdasdasdasd schrieb:
Normalerweise arbeite ich nicht mit manueller Speicherverwaltung, bin jetzt aber durch eine externe Vorgabe dazu gezwungen worden.
Manuell Speicher verwalten ist ja auch doof. Dabei macht man nur Fehler. Gib diese Verantwortung möglichst früh an "schlaue Objekte" ab.
Beispiel:
void ungeschickt(char const* filename) { FILE* f = fopen(filename,"r"); ... fclose(f); }void schlau(char const* filename) { std::ifstream f (filename); ... }Das schlaue daran ist, dass das ifstream-Objekt sich um die Resource kümmern, nicht du selbst. Es gilt also nicht nur um Speicher, sondern für alle möglichen Arten von Resourcen.
Wo kommt denn der Zeiger jetzt eigentlich her? Kannst du das nicht durch einen std::vector ersetzen? Sonst guck mal, ob boost::scoped_array vielleicht etwas für dich ist. Beides sind Beispiele für Klassen, die sich verantwortlich für reservierten Speicher fühlen und ihn automatisch wegräumen, wenn die entsprechenden Instanzen zerstört werden.