TImage assign TBitmap



  • Hallo zusammen,

    ich habe die folgende Funktion:

    void __fastcall TCaptureForm::Bildladen1Click(TObject *Sender)
    {
    	if (OpenPictureDialog1->Execute()){
    		TMemoryStream *Stream    = new TMemoryStream();
    		TJPEGImage    *Jpeg      = new TJPEGImage;
    		if (myPI != NULL) {
    			delete myPI;
    			myPI = NULL;
    		}
    		if (myBitmap == NULL) {
    			myBitmap = new Graphics::TBitmap;
    		}
    		else{
    			delete myBitmap;
    			myBitmap = NULL;
    			myBitmap = new Graphics::TBitmap;
            }
    		AnsiString extension = ExtractFileExt(OpenPictureDialog1->FileName);
    		extension = extension.LowerCase();
    		if (extension == ".jpg" || extension == ".jpeg") {
    			Stream->LoadFromFile(OpenPictureDialog1->FileName);
    			Jpeg->LoadFromStream(Stream);
    			myBitmap->Assign(Jpeg);
    
    		}
    		else{
    		   myBitmap->LoadFromFile(OpenPictureDialog1->FileName);
    
    		}
    		Image1->Picture->Assign(myBitmap);
    		if(Stream)
    		   delete Stream;
    		if(Jpeg)
    		   delete Jpeg;
    		myPI = new TProcessImage(myBitmap, path + "settings.ini");
    
    	}
    }
    

    Wenn ich sie zum ersten mal aufrufe, ist alles ok, myBitmap ist vorher NULL, daher wird die erste else-Verzweigung nicht aufgerufen (myBitmap ist eine globale Variable). Beim zweiten Aufruf bekomme ich in der delete myBitmap Zeile eine Exception InvalidPointerOperation. Ich vermute, das liegt daran, dass myBitmap an Image1 "assigned" ist. Ist diese Vermutung richtig und wenn ja, was muss ich ändern, muss ich vorher das assign irgendwie wieder "rückgängig" machen?

    Meine zweite Frage ist, ob ich myBitmap beim Beenden des Programms mit delete myBitmap zerstören muss oder ob das durch das Assign automatisch erledigt wird.

    Vielen Dank im Voraus

    Gruss
    Lodo2609



  • Und fröhlich grüßt das Speicherleck 😉
    Lies zunächst, was ich hier schrieb.

    Vermutlich ist die Fehlerursache, daß du an das neu erstellte TProcessImage-Objekt einen Zeiger auf das Bitmap übergibst und dieses mit der fortdauernden Existenz des Bitmaps rechnet. Hier wäre ein std::tr1::shared_ptr<> anstelle eines Zeigers angebracht.
    TPicture::Assign ist jedenfalls eher nicht daran schuld; es kopiert den Inhalt der Graphik, anstelle einen Verweis zu speichern (auch wenn TBitmap intern mit Referenzzählung arbeitet).


Anmelden zum Antworten