Fehler beim Laden von Texturen?



  • Die Arbeit am Programm (ein 3D-Spiel unter Linux) ist schon weit fortgeschritten, und nun passiert das Gefürchtete: ein nicht sicher rekonstruierbarer Pointer-Fehler. In der Startphase, wenn vor allem die Texturen geladen werden, bleibt das Programm hängen - manchmal auch nicht. Zwei- oder dreimal bekam ich sogar eine Fehlermeldung:

    Speicherzugriffsfehler
    free(): invalid pointer 0x8554268!
    

    Schon eine kleine Änderung am Quelltext (ein eingeschobener Kommentar) kann zur Folge haben, dass alles wieder ok zu sein scheint, bis dann plötzlich ...

    Nachstehend eine verdächtige Funktion. Ich kann zwar keinen Fehler entdecken, aber vielleicht seht Ihr ihn. Es geht darum, über SDL-Image eine PNG-Grafik zu laden und in eine Datenstruktur umzuspeichern:

    Im Header:

    typedef struct {
        unsigned short sizeX;
        unsigned short sizeY; 
        unsigned short sizeZ;
        unsigned short pitch;
        unsigned char *data;
    } IMAGE;
    
    IMAGE *ImageLoad (char *filename);
    

    Der Code:

    IMAGE *ImageLoad (char *filename)  {
    	int len = strlen (filename);
    	SDL_Surface *sdlImage;
    	unsigned char *sdldata;
    	IMAGE *result;
    	int x, y;
    
    	if (!strcmp (filename + len - 3, "png")) {
    		// 1. Bitmap in ein SDL-Surface laden
    		sdlImage = IMG_Load (filename);
        	if (sdlImage == NULL) {
    			Error ("couldn't load image file", filename);
    			return NULL;
    		}
    
    		// 2. IMAGE-Struktur allokieren
    		result = (IMAGE *) malloc (sizeof (IMAGE));
    		if (result == NULL) {
    			FatalError ("malloc of image failed", filename);
    			return NULL;
        	}
    		result->data = (unsigned char *) malloc (result->pitch * result->sizeY 
    			* sizeof (unsigned char));
    
    		// 3. Daten in IMAGE-Strutur schreiben
    		result->sizeX = sdlImage->w;
    		result->sizeY = sdlImage->h;
    		result->sizeZ = sdlImage->format->BytesPerPixel;
    		result->pitch = sdlImage->pitch;
    
        	if (SDL_MUSTLOCK(sdlImage)) {
        	    if (SDL_LockSurface (sdlImage) < 0) return NULL;
        	}
    
    		sdldata = sdlImage->pixels; 
    		for (y=0; y < result->sizeY; y++) {
    			for (x=0; x < result->pitch; x++) {
    				result->data [y * result->pitch + x] 
    				= sdldata [(result->sizeY - 1 - y) * result->pitch + x];	
    			}
    		}
    
        	if (SDL_MUSTLOCK (sdlImage)) SDL_UnlockSurface (sdlImage);
    
    		// 4. SDL-Surface wieder freigeben
    		SDL_FreeSurface (sdlImage);
    		return result;
    
    	} else {
    		Error ("unknown format", filename);
    		return NULL;
    	}
    }
    

    Und schließlich ein Aufruf der Funktion. Hier wird eine Textur geladen, in anderen Fällen wird die o.a. Funktion gebraucht, um z.B. eine Heightmap auszuwerten.

    GLuint LoadTexture (char *filename, int repeatable) {
        IMAGE *texImage;
    	GLuint texid;
    
        texImage = ImageLoad (filename);
        if (texImage == NULL) return 0;
    
    	// in diesem Fall (Textur) hier die Übergabe an OpenGL
    	// und Holen der Textur-ID
    
        free (texImage->data);
        free (texImage);
        return texid;    
    }
    

    Könnt Ihr einen Fehler erkennen? Es würde mich glücklich machen, wenn Ihr eine Macke entdecken würdet.


Anmelden zum Antworten