2017-12-17 5 views
0

Ich arbeite an einer der Aufgaben mit Bildbearbeitung (Blending und Zoom) und ich bin auf ein Problem gestoßen, das ich schwer zu überwinden habe.Zerstöre Vektoren von dynamischen Arrays via Destruktor in C++

Struktur meiner Anwendung

Klasse Bild

  • rgb Struktur: enthält Schwimmer und überladene Operatoren (sie abgeflachte Pixel sind).
  • Pixel: ein 1d Pixelfeld, das über Konstruktor initialisiert wird, um h * w
  • Klassendestruktor zu sein.

Destructor sieht ein wenig so ...

virtual ~Image() 
{ 
    if (pixels != NULL) 
     delete[] pixels; 
} 

Nun verwende ich eine andere Klasse Filter genannt, die sich von Bild erbt

Klasse Filter: public class Bild

  • Std :: Vektor von Image imgStack; Container für Bilder, die ich überblenden werde
  • Std :: Vektor von Rgb pixelBuffer; Ein Container für die Pixel für jedes Bild ein Pixel. Das ist nicht dynamisch, deshalb mache ich mir keine Sorgen, das zu löschen.

Destruktor für die abgeleitete Klasse.

~Blend() 
{ 
    delete &imageStack; 
} 

, was dieser Teil meiner main.cpp wie ... I 13 Bilder in das Blend-Objekt im Grunde renne

while (userInput != 5) 
{ 
    switch(userInput) 
    case 1: 
    { 
     Blend *meanImage = new Blend(3263, 2505, 13); 
     meanImage->writePPM("Mean_" + std::to_string(count) + ".ppm");//every iteration, the file name is unique 
     meanImage->~Blend(); 
    } 
} 

In meinem main.cpp sieht, die die Bilder in den Vektor speichert Container, um alle meine Funktionen auf zu tun. Während der Laufzeit ist der verwendete Speicherplatz etwa 1,3 GB, aber da sich mein Objekt in einer Schleife befindet (ich habe ein Menü für mehrere Funktionen), verlässt das Objekt den Bereich normalerweise nicht, so dass der Destruktor nicht automatisch aufgerufen wird, also rufe ich an es mag das manuell; medianImage-> ~ Mischung(); Nun sagt der ganze Fehler, dass meine Anwendung "einen Haltepunkt ausgelöst hat" und das ist es ... Anmerkung, kein Haltepunkt ist irgendwo gefunden. Ich bin mir bewusst, dass es generell schlecht ist, dynamische Arrays zu verwenden, weil es alle Arten von Speicherproblemen verursacht (wenn es von mir erledigt wird), aber ich möchte das beheben, damit ich weiß, wie ich diese in Zukunft lösen kann.

Wenn Sie Fragen zum Code haben, kann ich Snippers veröffentlichen.

Edit: hier ist eine meiner Blend-Klasse.

#pragma once 
#include "stdafx.h" 
#include "Image.h" 
#include <vector> 
#include <string> 
class Blend : public Image 
{ 
private: 
    std::vector<Image> imageStack; 
    std::vector<Rgb*> pixelBuffer;//only works with pointers (no copying) 
    int m_noOfImages; 

    Rgb* getMedianFromSet(); 
    Rgb getMeanFromSet(); 
    Rgb getStdDev(Rgb meanPix); 
public: 
    Blend(int width = 0, int height = 0, int noOfImages = 0):Image(width, height), m_noOfImages(noOfImages), imageStack(noOfImages), pixelBuffer(noOfImages) 
    {} 
public: 
    void stack(bool push = true); 
    void meanBlend(); 
    void medianBlend(); 
    void sigmaClipping(float sigma = 0.5f); 

    ~Blend() 
    { 
     delete &imageStack; 
    } 
}; 
+0

Sie sollten den Destruktor nicht aufrufen. Stattdessen lösche mainImage; oder besser noch nicht neu verwenden und dort überhaupt löschen. Modernes C++ rät von der Verwendung von new/delete ab. – drescherjm

+5

'delete & imageStack;' Das sieht _sehr_ falsch aus. – tkausl

+0

Wahrscheinlich erhalten Sie undefiniertes Verhalten. –

Antwort

1
#pragma once 
#include "stdafx.h" 
#include "Image.h" 
#include <vector> 
#include <string> 
#include <memory> 
class Blend : public Image 
{ 
private: 
    std::vector<Image> imageStack; 
    // Changed to shared_ptr<T> could use unique_ptr<T> depending on need. 
    std::vector<std::shared_ptr<Rgb>> pixelBuffer;//only works with pointers (no copying) 
    int m_noOfImages; 

    Rgb* getMedianFromSet(); 
    Rgb getMeanFromSet(); 
    Rgb getStdDev(Rgb meanPix); 
public: 
    Blend(int width = 0, int height = 0, int noOfImages = 0):Image(width, height), m_noOfImages(noOfImages), imageStack(noOfImages), pixelBuffer(noOfImages) 
    {} 
public: 
    void stack(bool push = true); 
    void meanBlend(); 
    void medianBlend(); 
    void sigmaClipping(float sigma = 0.5f); 

    // Clear Entire Buffer 
    void cleanup() { 
     // When using the heap with smart pointers 
     for (auto item : containerVariable) { 
      item.reset(); 
      item = nullptr; 
     } 
     containerVariable.clear(); 
    } 

    // Remove Single Element 
    void remove(unsigned idx) { 
     // Write function to remove a single element from vector 
    } 

    ~Blend() 
    { 
     // This is definitely wrong here: You are trying to delete a reference 
     // to a template container that is storing `Image` objects that 
     // are on the stack. 
     // delete &imageStack; 
    } 
}; 

Es ist besser, eine Funktion zu schreiben Speicher aufzuräumen, und bestimmte Elemente aus den Behältern zu entfernen, wenn dynamische Speicher mit, als es einer Klasse destructor zu verwenden ist.