Error while Free()ing image texture data

Started by
3 comments, last by Kibble 19 years, 7 months ago
This error is occurring in an OpenGL program, but it seems more general in nature, so I'm posting it here. I am converting some of NeHe's stuff to SDL and a small game engine. I took Lesson 17, textured fonts, and put the font routines and functions into a class called CEngineFont. The functions aren't modified at all, other than that they exist in a class now. In the following code, when I get to the line that frees the image texture data, the program crashes. Here is the error: HEAP[Engine.exe]: Invalid Address specified to RtlValidateHeap( 00320000, 048D0028 ) Unhandled exception at 0x77f75a58 in Engine.exe: User breakpoint. And here is the function:

int CEngineFont::LoadGLTextures()                                    // Load Bitmaps And Convert To Textures
{
        int Status=FALSE;                               // Status Indicator
        AUX_RGBImageRec *TextureImage[2];               // Create Storage Space For The Textures
        memset(TextureImage,0,sizeof(void *)*2);        // Set The Pointer To NULL

        if ((TextureImage[0]=LoadBMP("Data/Font.bmp")) &&
			(TextureImage[1]=LoadBMP("Data/Bumps.bmp")))
        {
                Status=TRUE;                            // Set The Status To TRUE
                glGenTextures(2, &texture[0]);          // Create Two Texture

				for (loop=0; loop<2; loop++)
				{
	                glBindTexture(GL_TEXTURE_2D, texture[loop]);
			        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
				    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
					glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[loop]->sizeX, TextureImage[loop]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop]->data);
				}
        }
		for (loop=0; loop<2; loop++)
		{
	        if (TextureImage[loop])							// If Texture Exists
		    {
			        if (TextureImage[loop]->data)			// If Texture Image Exists
				    {
					        free(TextureImage[loop]->data);	// Free The Texture Image Memory
					}
					free(TextureImage[loop]);				// Free The Image Structure
			}
		}
        return Status;                                  // Return The Status
}

The lines that is crashing is:

free(TextureImage[loop]->data);
If you need more code, just let me know. Thanks for any help you can offer.
-Todd"Windows dectected that your mouse has moved. Please reboot for the changes to take effect"
Advertisement
In the project settings, try changing from whatever it is now to the DLL version of it. LoadBMP is probably in another DLL, and if you aren't using the same heap it will give you that error.

edit: The runtime libraries.
Clarifying Kibble's statement;

Wherever LoadBMP is, make sure it's in a static-linked library, not a DLL. If it is in DLL, there will most likely be a "FreeBMP" or somesuch call in the same DLL that will clear it off the DLL's heap.
RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
Thanks, but LoadBMP is a function in the same class. Here is the complete class - .h file, then .cpp:

#pragma once#include <windows.h>#include <stdio.h>			// Header File For Standard Input/Output#include <GL/gl.h>#include <GL/glu.h>#include <GL/glaux.h>		// Header File For The Glaux Libraryclass CEngineFont{public:	CEngineFont(void);	virtual ~CEngineFont(void);	GLvoid glPrint(GLint x, GLint y, char *string, int set);private:	GLuint	base;				// Base Display List For The Font Set	GLuint	texture[2];			// Storage For Our Font Texture	GLuint	loop;				// Generic Loop Variable			int LoadGLTextures();	GLvoid BuildFont(GLvoid);	GLvoid KillFont(GLvoid);};


#include ".\enginefont.h"CEngineFont::CEngineFont(void){	LoadGLTextures();	BuildFont();}CEngineFont::~CEngineFont(void){	KillFont();}AUX_RGBImageRec *LoadBMP(char *Filename)                // Loads A Bitmap Image{        FILE *File=NULL;                                // File Handle        if (!Filename)                                  // Make Sure A Filename Was Given        {                return NULL;                            // If Not Return NULL        }        File=fopen(Filename,"r");                       // Check To See If The File Exists        if (File)                                       // Does The File Exist?        {                fclose(File);                           // Close The Handle                return auxDIBImageLoad(Filename);       // Load The Bitmap And Return A Pointer        }        return NULL;                                    // If Load Failed Return NULL}int CEngineFont::LoadGLTextures()                                    // Load Bitmaps And Convert To Textures{        int Status=FALSE;                               // Status Indicator        AUX_RGBImageRec *TextureImage[2];               // Create Storage Space For The Textures        memset(TextureImage,0,sizeof(void *)*2);        // Set The Pointer To NULL        if ((TextureImage[0]=LoadBMP("Data/Font.bmp")) &&			(TextureImage[1]=LoadBMP("Data/Bumps.bmp")))        {                Status=TRUE;                            // Set The Status To TRUE                glGenTextures(2, &texture[0]);          // Create Two Texture				for (loop=0; loop<2; loop++)				{	                glBindTexture(GL_TEXTURE_2D, texture[loop]);			        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);				    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);					glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[loop]->sizeX, TextureImage[loop]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop]->data);				}        }		for (loop=0; loop<2; loop++)		{	        if (TextureImage[loop])							// If Texture Exists		    {			        if (TextureImage[loop]->data)			// If Texture Image Exists				    {					        free(TextureImage[loop]->data);	// Free The Texture Image Memory					}					free(TextureImage[loop]);				// Free The Image Structure			}		}        return Status;                                  // Return The Status}GLvoid CEngineFont::BuildFont(GLvoid)								// Build Our Font Display List{	float	cx;											// Holds Our X Character Coord	float	cy;											// Holds Our Y Character Coord	base=glGenLists(256);								// Creating 256 Display Lists	glBindTexture(GL_TEXTURE_2D, texture[0]);			// Select Our Font Texture	for (loop=0; loop<256; loop++)						// Loop Through All 256 Lists	{		cx=float(loop%16)/16.0f;						// X Position Of Current Character		cy=float(loop/16)/16.0f;						// Y Position Of Current Character		glNewList(base+loop,GL_COMPILE);				// Start Building A List			glBegin(GL_QUADS);							// Use A Quad For Each Character				glTexCoord2f(cx,1-cy-0.0625f);			// Texture Coord (Bottom Left)				glVertex2i(0,0);						// Vertex Coord (Bottom Left)				glTexCoord2f(cx+0.0625f,1-cy-0.0625f);	// Texture Coord (Bottom Right)				glVertex2i(16,0);						// Vertex Coord (Bottom Right)				glTexCoord2f(cx+0.0625f,1-cy);			// Texture Coord (Top Right)				glVertex2i(16,16);						// Vertex Coord (Top Right)				glTexCoord2f(cx,1-cy);					// Texture Coord (Top Left)				glVertex2i(0,16);						// Vertex Coord (Top Left)			glEnd();									// Done Building Our Quad (Character)			glTranslated(10,0,0);						// Move To The Right Of The Character		glEndList();									// Done Building The Display List	}													// Loop Until All 256 Are Built}GLvoid CEngineFont::KillFont(GLvoid)									// Delete The Font From Memory{	glDeleteLists(base,256);							// Delete All 256 Display Lists}GLvoid CEngineFont::glPrint(GLint x, GLint y, char *string, int set)	// Where The Printing Happens{	if (set>1)	{		set=1;	}	glBindTexture(GL_TEXTURE_2D, texture[0]);			// Select Our Font Texture	glDisable(GL_DEPTH_TEST);							// Disables Depth Testing	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix	glPushMatrix();										// Store The Projection Matrix	glLoadIdentity();									// Reset The Projection Matrix	glOrtho(0,640,0,480,-1,1);							// Set Up An Ortho Screen	glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix	glPushMatrix();										// Store The Modelview Matrix	glLoadIdentity();									// Reset The Modelview Matrix	glTranslated(x,y,0);								// Position The Text (0,0 - Bottom Left)	glListBase(base-32+(128*set));						// Choose The Font Set (0 or 1)	glCallLists(GLsizei(strlen(string)),GL_BYTE,string);			// Write The Text To The Screen	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix	glPopMatrix();										// Restore The Old Projection Matrix	glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix	glPopMatrix();										// Restore The Old Projection Matrix	glEnable(GL_DEPTH_TEST);							// Enables Depth Testing}
-Todd"Windows dectected that your mouse has moved. Please reboot for the changes to take effect"
Is auxDIBImageLoad one of your functions as well? If not, its still going to allocate on a different heap if the runtime libraries aren't the DLL version. Like Wyreframe said, there is most likely a FreeBMP funtion for you to use.

This topic is closed to new replies.

Advertisement