Vermeiden von memory leaks bei der Lagerung von OpenCV Mat-Objekte in STL-Containern

Ich bin mit OpenCV und ich wollen speichern Sie eine Anzahl von Bildern (Mat Objekte) in einem Vektor. Ich habe erklärt der Vektor wie folgt zu speichern Zeiger auf Mat Objekte.

std::vector<Mat*> images;

Den Mat Objekte erzeugt werden, indem die new Schlüsselwort, und dann Hinzugefügt, um den Vektor.

Mat *img = new Mat(height, width, CV_8UC3);
//set the values for the pixels here
images.push_back(img);

Wie würde ich sicherstellen, dass ich den Speicher frei, indem die besetzten Mat Objekte um Speicherverluste zu vermeiden?

Was ich gerade mache ist Folgendes:

Mat *im = images.at(index);
//process and display image here
delete(im);

Valgrind ist reporing eine mögliche memory leak mit Referenz auf den erzeugten Mat-Objekte. Bin ich etwas fehlt?

Edit:

Ok. Anscheinend ist es besser zu vermeiden, mit Mat Zeiger und dynamische Zuweisung Mat mit new. Ich habe meine modifizierten code zu verwenden std::vector<Mat> statt. Ich sehe aber noch einige Blöcke, die zugeteilt wurden, die von Mat möglicherweise verloren in der Valgrind-Bericht. Ich merke auch, dass die Speicherauslastung steigt stetig, während das Programm ausgeführt wird.

Lassen Sie mich klarstellen, was ich Tue. Ich erschaffe Bilder, die in einer Funktion und legt Sie in einem Zwischenspeicher (intern mit std::deque). Dieser Puffer wird dann zugegriffen, indem eine andere Funktion zum abrufen und Bild, und übergeben Sie es an eine andere Funktion, die führt die Bearbeitung und das rendering.

class Render {
   public:
      void setImage(Mat& img) {
         this->image = img;
      }

      void render() {
         //process image and render here
      }
   private:
      Mat image;
}

Thread, der kontinuierlich holt Bilder aus dem Puffer und stellt Sie dar.

void* process(void *opaque) {

   ImageProcessor *imgProc = (ImageProcessor*) opaque;
   Mat img;


   while (imgProc->isRunning) {
      //get an image from the buffer
      imgProc->buffer->getFront(img);

      //set the image
      imgProc->renderer->setImage(img);

      //process and render
      imgProc->renderer->render();
   }

}

Nun, alles, was übergeben wird, die als Objekt-Referenzen (D. H. Mat&). Ich gehe davon aus, dass nach dem abrufen eines Bildes aus dem Puffer und an die render-Funktion, die nur die Referenz zu diesem Objekt wird in dieser Funktion. Deshalb, wenn ich ein weiteres Bild, es wird nicht länger eine Referenz auf das Objekt, und es wird zerstört werden. Aber Valgrind gibt mir die folgende:

25,952,564 bytes in 11 blocks are possibly lost in loss record 14,852 of 14,853
  in ImageProcessor::generateImage() in ImageProcessor.cpp:393
  1: malloc in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
  2: cv::fastMalloc(unsigned long) in /usr/local/lib/libopencv_core.so.2.4.2
  3: cv::Mat::create(int, int const*, int) in /usr/local/lib/libopencv_core.so.2.4.2
  4: cv::Mat::create(int, int, int) in /usr/local/include/opencv2/core/mat.hpp:353
  5: cv::Mat::Mat(int, int, int) in /usr/local/include/opencv2/core/mat.hpp:75
  ...

Und hier ist generateImage():

void generateImage() {
   Mat img(h, w, CV_8UC3); 
   //set values of pixels here
   this->buffer->pushBack(img);
}
  • Der Mat-Klasse verwaltet die Zuweisung von Speicher und hat die Referenz-Zählung, so dass std::vector<Mat> erledigt die Arbeit für Sie nur noch und kopiert den Zeiger plus size Informationen ohne unnötige Zuweisungen und Kopien der großen Matrix-Inhalten.
  • Ich habe aktualisiert die Frage, wobei einige Teile des Codes nach dem Update es, wie Sie vorgeschlagen. Ich noch Begegnung ein Speicher-Leck, obwohl das problem noch besteht.
  • Die Teile von deinem code hier funktionieren sollte. Können Sie erläutern, wie ein bit auf, das undurchsichtige Zeiger? Wo kommt es her, wie wird es initialisiert, und wer besitzt es und ruft den Destruktor der ImageProcessor wenn es nicht mehr benötigt wird? Beachten Sie, dass void * opaque=new ImageProcessor; do_stuff(opaque); free opaque; ruft den Konstruktor der ImageProcessor aber der Destruktor von void).
  • Die transparenten Zeiger ist im Grunde ein Zeiger auf eine ImageProcessor Objekt. Wie ich bereits erwähnt process() ist eine thread-Funktion. Ich erstelle ein thread mit dem Pthread - Bibliothek und übergeben Sie einen Zeiger auf process() und einen Zeiger auf ein Objekt, das ist im Grunde die parameter der thread-Funktion. Dies ist, wie die threads erstellt werden, mit pthread_create(). Hier, ich bin nur auf der Durchreise einen Verweis auf ImageProcessor so dass der thread die Methoden aufrufen. Wann und wo der Destruktor ImageProcessor aufgerufen wird, sollte das kein problem sein. Da bin ich auf das entfernen der Mat Objekte aus dem Puffer.
InformationsquelleAutor informer2000 | 2013-11-01
Schreibe einen Kommentar