Skip to main content

Thread: Stack corruption driving me insane


hi guys,

i've been stuck on problem ages , can't seem figure out, i'm hoping whoever reads can. i'm writing small game engine hobby in spare time, it's not working planned.

problem whenever member function 'loadtexture(char *cname)' called msvc debugger says "run-time check failure #2 - stack around variable 'image' corrupted." have no problem googling programming problems, i've been stuck on 1 hours without straight answer.

here header file class:
code:
// graphicsdevice.h  #ifndef h_graphics_device #define h_graphics_device  #include "graphicsinstance.h" #include <sfml/window.hpp> #include <sfml/graphics.hpp> #include <gl/gl.h> #include <gl/glu.h> #include <vector>  using std::vector;  #define max_windows 10 #define max_entities 10000 #define array_resize_amount 50 //defines how arrays resize (50 means arrays expand 50 spaces @ time) #define max_depth 100000//the maximum positive or negative number graphics instance's depth can  using namespace std;  //this can inhereted purposes of expanding engine rendering api class graphicsdevice { public: 	graphicsdevice(void); 	~graphicsdevice(void); 	int			createrenderingwindow(int winwidth, int winheight, int colourdepth, char *title, bool fullscreen, int antialiasing); 	int			destroyrenderingwindow(); 	int			updategraphics(); 	int			updatewindow(); 	nanotexture *loadtexture(char *cname);//loads texture , returns pointer it, or pointer if loaded 	int	instanceattach(graphicsinstance *instance); 	int instancedetach(graphicsinstance *instance); 	void setbackgroundcolour(float red, float green, float blue); 	float getframetime(void); 	void resortdepth(void); 	sf::renderwindow *getsfmlwindow();  private: 	//private member functions: 	void reshape(int x, int y);		//reshapes opengl viewport given new width , height of window 	void rotatepoint(float cx, float cy, float angle, float *px, float *py); //rotates (px, py) around (cx, cy)  	//resorts graphicsinstances front based on depth, n number of graphicsinstances 	void sortentities (int n);  	//rendering settings: 	sf::renderwindow *wwindow; 	bool bwinfocused; 	int iwinwidth; 	int iwinheight; 	bool bwinclosed; 	int icolourdepth; 	int iantialiasing;  	//instance information: 	unsigned int	iinstancecount; 	vector<graphicsinstance *> entities; 	unsigned int iinstancearraysize;  	//resources: 	unsigned int itexturecount; 	unsigned int itexturearraysize; 	vector<auto_ptr<nanotexture> > ptextures; 	vector<gluint>	vtexture;  	//bg colour: 	float fbgred; 	float fbggreen; 	float fbgblue;  	//depth sorting: 	bool bdepthsortneeded;  	//only testing purposes: 	int x; 	float fps; };  #endif
and here source file:
code:
#include "stdafx.h" #include "graphicsdevice.h"  graphicsdevice::graphicsdevice(void) { 	//instances 	iinstancecount		= 0; 	iinstancearraysize	= 0; 	wwindow				= null;  	//rendering settings: 	bwinfocused = false; 	iwinwidth	= 0; 	iwinheight	= 0; 	bwinclosed	= true; 	icolourdepth	= 0; 	iantialiasing	= 0;  	//resources: 	itexturecount		= 0; 	itexturearraysize	= 0;  	//bg colour: 	float fbgred	= 0; 	float fbggreen	= 0; 	float fbgblue	= 0;  	//depth sorting: 	bdepthsortneeded = false;  	//only testing purposes: 	x		= 0; 	fps		= 0; }  graphicsdevice::~graphicsdevice(void) { 	//release textures 	for (uint i=0; i<itexturecount; i++)  	{ 		std::cout << "deleting texture id " << << " out of " << itexturecount-1 << endl; 		//gldeletetextures(1, (gluint*)ptextures[i].get()->textureid); 		gldeletetextures(1, (gluint*)vtexture[i]); 	}  	if (bwinclosed == false) 	{ 		wwindow->close(); 		delete wwindow; 	} }  int graphicsdevice::createrenderingwindow(int winwidth, int winheight, int colourdepth, char *title, bool fullscreen, int antialiasing) { #ifdef _debug 	cout << "creating rendering window following properties:\n" << "\twidth: " << winwidth << "\n\theight: " << winheight  		<< "\n\tcolour depth: " << colourdepth << "\n\tfullscreen: " << fullscreen << "\n\tanti-aliasing: " << antialiasing <<"\n"; #endif  	if (bwinclosed == false) 	{ #ifdef _debug 		cout << "error: cannot create new rendering window because 1 exists\n"; #endif 	}  	//record arguments 	iantialiasing = antialiasing; 	icolourdepth = colourdepth; 	iwinwidth = winwidth; 	iwinheight = winheight;  	//set settings 	sf::windowsettings settings; 	settings.depthbits         = 24; // request 24 bits depth buffer 	settings.stencilbits       = 8;  // request 8 bits stencil buffer 	settings.antialiasinglevel = iantialiasing;  // request 2 levels of antialiasing  	//create new window 	if (fullscreen == true) 	{ 		wwindow = new sf::renderwindow(sf::videomode(iwinwidth, iwinheight, icolourdepth),  		title, sf::style::fullscreen, settings); 		 	} 	else 	{ 		wwindow = new sf::renderwindow(sf::videomode(iwinwidth, iwinheight, icolourdepth),  		title, /*sf::style::fullscreen, sf::style::close*/sf::style::resize, settings); 	}  	//windows start focused: 	bwinfocused = true; 	bwinclosed = false;  #ifdef _debug 	cout << "window created successfully\n"; #endif  	return 0; }  int graphicsdevice::destroyrenderingwindow() { 	//destroy window 	if (bwinclosed == false) 	{ 		wwindow->close(); 		bwinclosed = true; #ifdef _debug 		cout << "rendering window destroyed.\n"; #endif 	} 	else 	{ #ifdef _debug 		cout << "error: cannot destroy rendering window because doesn't exist.\n"; #endif 		return -1; 	}  	return 0; }  int graphicsdevice::updategraphics() { 	//check if window has been closed 	if (bwinclosed == true) 	{ #ifdef _debug 		cout << "error: cannot swap buffers closed window.\n"; #endif 		return -1; 	}  	//check see if graphicsinstances need put in order 	if (bdepthsortneeded == true) 	{ 		sortentities(iinstancecount); 		bdepthsortneeded = false; 	}  	//must called before rendering window (only needed when doing multiple windows meh) 	wwindow->setactive();  	//resize opengl viewport window rendering. todo: put on resize event 	reshape(iwinwidth, iwinheight);  	//enable depth testing 	glcleardepth(1.0f);							// depth buffer setup 	glenable(gl_depth_test);						// enables depth testing 	gldepthfunc(gl_lequal); 	 	//set clear colour 	glclearcolor(fbgred, fbggreen, fbgblue, 1);  	//clear screen 	glclear(gl_color_buffer_bit | gl_depth_buffer_bit);  	int vport[4];  	glgetintegerv(gl_viewport, vport);  	glmatrixmode(gl_projection); 	glpushmatrix(); 	glloadidentity();  	glortho(0, vport[2], 0, vport[3], max_depth*-1, max_depth);//last 2 arguments near (close screen) , far (view distance) clipping 	glmatrixmode(gl_modelview); 	glpushmatrix();  	//prevents pixel blur occuring since pixel coordinates not aligned window 	glloadidentity(); 	gltranslatef (0.375, 0.375, 0);//0.5 formerly 0.375  	//enable transparency rendering in gl primatives (if glenable (gl_blend);) 	glblendfunc (gl_src_alpha, gl_one_minus_src_alpha);  	//make depth buffer read while render(for transparency effects) //now don"t need because being drawn in order 	gldepthmask(gl_false);  	//variables need rendering: 	nanotexture *ntrendertexture = null; //this used handle each graphicsinstance's texture 	float		frenderangle	= 0.0f; //this used handle each graphicsinstance's rotation 	float		fdepth			= 0;	//this used handle each graphicsinstance's depth 	float		frenderpointtlx, frenderpointtrx, frenderpointblx, frenderpointbrx; //the x points opengl render 	float		frenderpointtly, frenderpointtry, frenderpointbly, frenderpointbry; //the y points opengl render 	 	//render entities: 	for (unsigned int = iinstancecount-1; i>=0; i--)//for attached instances graphicsinstance (in reverse render properly) 	{ 		if (entities[i])				//if 1 exists 		{ 			if (entities[i]->getvisible() == true)	//if graphicsinstance set visible 			{ 				ntrendertexture = entities[i]->gettexture(); 				if (ntrendertexture != null)				//if graphicsinstance has image render 				{ 					//collect needed details given instance: 					frenderangle	= entities[i]->getrotation(); 					fdepth			= (float)(entities[i]->getdepth()*-1);//we multiply -1 higher depth goes deeper screen  					//cout << "drawing instance @ depth " << entities[i]->getdepth() << endl;  					//set initial position of 4 points: 					frenderpointtlx = entities[i]->getpositionx() - entities[i]->getoriginx(); 					frenderpointtly = entities[i]->getpositiony() - entities[i]->getoriginy();  					frenderpointtrx = frenderpointtlx + entities[i]->getscalex(); 					frenderpointtry = frenderpointtly;  					frenderpointblx = frenderpointtlx; 					frenderpointbly = frenderpointtly + entities[i]->getscaley();  					frenderpointbrx = frenderpointtrx; 					frenderpointbry = frenderpointbly;  					//rotate 4 points: 					if (frenderangle != 0)//if rotation has been modified 					{ 						rotatepoint(entities[i]->getpositionx(), entities[i]->getpositiony(), frenderangle, &frenderpointtlx, &frenderpointtly); 						rotatepoint(entities[i]->getpositionx(), entities[i]->getpositiony(), frenderangle, &frenderpointtrx, &frenderpointtry); 						rotatepoint(entities[i]->getpositionx(), entities[i]->getpositiony(), frenderangle, &frenderpointbrx, &frenderpointbry); 						rotatepoint(entities[i]->getpositionx(), entities[i]->getpositiony(), frenderangle, &frenderpointblx, &frenderpointbly); 					}  					// bind our texture 					glenable(gl_texture_2d); 					glbindtexture(gl_texture_2d, (gluint)ntrendertexture->textureid); 					glcolor4f(1.f, 1.f, 1.f, 1.f);  					//modify rendering settings 				if (entities[i]->getqualitytransparent() == false) 					{ 						glalphafunc(gl_greater, (glclampf)0.9);//set alpha test ignore pixels below 90% alpha, , make top 10% opaque 						glenable(gl_alpha_test);//enable alpha test 					} 					else 					{ 						glenable(gl_blend);//enable alpha blending 					}  					//check if depth appropriate (debug only) #ifdef _debug 					if (fdepth < (max_depth*-1) || fdepth > max_depth) 					{ 						cout << "warning: attempting render object depth less -" << max_depth 							<< " or greater " << max_depth << ". texture may not appear\n"; 					} #endif  					/*render graphicsinstance using collected details (all points on  					y axis multiplied -1 invert y axis higher y moves 					points downwards. not second argument of gltexcoord2f must 					be inverted)*/ 					glbegin(gl_quads);  					//bottom-left 					gltexcoord2f(0, 1); 					glvertex3f(frenderpointblx, (frenderpointbly * -1) + iwinheight, fdepth);  					//bottom-right 					gltexcoord2f(1, 1); 					glvertex3f(frenderpointbrx, (frenderpointbry * -1) + iwinheight, fdepth);  					//top-right 					gltexcoord2f(1, 0); 					glvertex3f(frenderpointtrx, (frenderpointtry * -1) + iwinheight, fdepth);  					//top-left 					gltexcoord2f(0, 0); 					glvertex3f(frenderpointtlx, (frenderpointtly * -1) + iwinheight, fdepth);  					glend();  					//unmodify rendering settings 					if (entities[i]->getqualitytransparent() == false) 					{ 						gldisable(gl_alpha_test);//enable alpha test 					} 					else 					{ 						gldisable(gl_blend);//enable alpha blending 					} 				} 			} 		} 		else 		{ #ifdef _debug 			cout << "bug: null instance attached\n"; #endif 		}  		//check if on last loop(fixes bug loop running in reverse) 		if (i==0) 			break; 	}  	//make depth buffer writable again (for transparency effects) //now don"t need because being drawn in order 	gldepthmask(gl_true);  #ifdef _debug 	//display frame time 	x++; 	fps += getframetime();  	if (fps > 5) 	{ 		cout << "fps: " << x/(float)5 << endl; 		x = 0; 		fps = 0; 	}  	/* 	if (x > 20000) 	{ 		cout << "average fps:" << fps/(float)x << endl; 		x = 0; 		fps = 0; 	}*/ #endif  	//update window 	wwindow->display();  	return 0; }  int graphicsdevice::updatewindow() { 	sf::event event; 		 	while (wwindow->getevent(event)) 	{ 		// window closed 		if (event.type == sf::event::closed) 		{ 			wwindow->close(); 			bwinclosed = true; 		}  		// window resize 		if (event.type == sf::event::resized) 		{ 			iwinwidth = event.size.width; 			iwinheight = event.size.height; 		}  		// window focused 		if (event.type == sf::event::gainedfocus) 		{ 			bwinfocused = true; 		}  		// window focused 		if (event.type == sf::event::lostfocus) 		{ 			bwinfocused = false; 		} 	} 	return 0; }  nanotexture *graphicsdevice::loadtexture(char *cname) { 	unsigned int itex, n = 0; 	 	// have texture? if so, ignore 	for (itex=0; itex<itexturecount; itex++)  	{ 		if (ptextures[itex].get()->sname.c_str()==cname)  		{ 			return ptextures[itex].get();//error non fatal 		} 	}  	// allocate array_resize_amount new memory slots textures if necessary 	if (itexturecount == itexturearraysize)  	{ 		itexturearraysize += array_resize_amount; 		ptextures.resize(itexturearraysize); 		vtexture.resize(itexturearraysize); #ifdef _debug 		cout << "expanding texture memory " << itexturearraysize << " textures\n"; #endif 	}   	//create new nanotexture 	ptextures[itexturecount].reset(new nanotexture);  	//save texture name 	ptextures[itexturecount].get()->sname = cname;  	//create new sf::image 	sf::image image;  	//loads texture in sfml  #ifdef _debug  	cout << "loading '" << ptextures[itexturecount].get()->sname << "' id " << itexturecount << "\n"; #endif  	if (image.loadfromfile(ptextures[itexturecount].get()->sname)) 	{ #ifdef _debug 		cout << "error: failed loading texture '" << ptextures[itexturecount].get()->sname << "'\n"; #endif 		return null; 	}  	//record textures dimensions 	ptextures[itexturecount].get()->fwidth	= (float)image.getwidth(); 	ptextures[itexturecount].get()->fheight	= (float)image.getheight();  	//record opengl info texture 	glgentextures(1, &vtexture[itexturecount]); 	glbindtexture(gl_texture_2d, vtexture[itexturecount]); 	gltexparameteri(gl_texture_2d, gl_texture_mag_filter, gl_linear); 	gltexparameteri(gl_texture_2d, gl_texture_min_filter, gl_linear_mipmap_linear); 	glubuild2dmipmaps(gl_texture_2d, gl_rgba, image.getwidth(), image.getheight(),  		gl_rgba, gl_unsigned_byte, image.getpixelsptr()); 	 	//records texture id 	ptextures[itexturecount].get()->textureid = (unsigned int)vtexture[itexturecount];  	//we have texture loaded	 	itexturecount++;  	//everything 	return ptextures[itexturecount-1].get();  }  int graphicsdevice::instanceattach(graphicsinstance *instance) { 	//check if given instance real 	if (!instance) 	{ #ifdef _debug 		cout << "error: cannot attach non-valid graphicsinstance\n"; #endif 		return -1; 	}  	//check if instance exists 	for (unsigned int = 0; i<iinstancearraysize; i++) 	{ 		if (entities[i]==instance) 		{ 			return 0; 		} 	}  	//check if have room more entities. if not, make room. 	while (iinstancecount>=iinstancearraysize) 	{ 		iinstancearraysize += array_resize_amount; 		entities.resize(iinstancearraysize); 	}  	//point instance 	entities[iinstancecount] = instance; 	 	//make sure knows it's attached 	if (entities[iinstancecount]->getattached() == false)//if doesn't know 		entities[iinstancecount]->attach(this);  	iinstancecount++; 	return 0; }  int graphicsdevice::instancedetach(graphicsinstance *instance) { 	//check if instance exists 	for (unsigned int = 0; i<iinstancearraysize; i++) 	{ 		if (entities[i]==instance) 		{ 			//make sure instance knows it's being detached 			if (entities[i]->getattached() == true)//if doesn't know  //i formerly iinstancecount 				entities[i]->attach(this);  			//shift entities above requested 1 down list 1 slot 			for (unsigned int ii = i; ii<iinstancearraysize-1; ii++)	//run loop till second last instance 			{ 				entities[ii] = entities[ii+1];//make 1 equal 1 in front of 			}  			entities[iinstancearraysize-1] = null;  			//decrement total number of entities 			iinstancecount -= 1;  			//shrink array if needed 			if ((iinstancearraysize-i)>array_resize_amount) 			{ 				iinstancearraysize -= array_resize_amount; 				entities.resize(iinstancearraysize); 			}  			return 0; 		} 	}  	//if nothing found #ifdef _debug 	cout << "error: can't detach graphicsinstance doesn't exist\n"; #endif 	return -1; }  void graphicsdevice::setbackgroundcolour(float red, float green, float blue) { 	fbgred		= red; 	fbggreen	= green; 	fbgblue		= blue; }  float graphicsdevice::getframetime(void) { 	return wwindow->getframetime(); }  void graphicsdevice::reshape(int x, int y) { 	if (y == 0 || x == 0) return;  //nothing visible then, return 	glviewport(0, 0, x, y); }  void graphicsdevice::rotatepoint(float cx, float cy, float angle, float *p_x, float *p_y) {   float s = sin(angle);   float c = cos(angle);    // translate point origin:   *p_x -= cx;   *p_y -= cy;    // rotate point   float xnew = (*p_x) * c - (*p_y) * s;   float ynew = (*p_x) * s + (*p_y) * c;    // translate point back:   *p_x = xnew + cx;   *p_y = ynew + cy; }  void graphicsdevice::resortdepth(void) { 	//this means sort depths before frame rendered, preventing multiple changes 	//in depth during 1 frame wasting cpu cycles 	bdepthsortneeded = true; }  void graphicsdevice::sortentities (int n) { 	graphicsinstance *t; // temporary value     unsigned int n = n, parent = n/2, index, child; // heap indexes     // loop until array sorted     (;;)  	{          if (parent > 0)  		{              // first stage - sorting heap              t = entities[--parent];  // save old value t         }  		else  		{             // second stage - extracting elements in-place             n--;						// make heap smaller             if (n == 0) return;			// when heap empty, done             t = entities[n];			// save lost heap entry temporary             entities[n] = entities[0];	// save root entry beyond heap         }          // insert operation - pushing t down heap replace parent         index = parent; // start @ parent index         child = index * 2 + 1; // left child index         while (child < n)  		{             // choose largest child             if (child + 1 < n  &&  entities[child + 1]->getdepth() > entities[child]->getdepth())  			{                 child++; // right child exists , bigger             }             // largest child larger entry?             if (entities[child]->getdepth() > t->getdepth())  			{                 entities[index] = entities[child]; // overwrite entry child                 index = child; // move index child                 child = index * 2 + 1; // left child , go around again             }  			else  			{                 break; // t's place found             }         }         // store temporary value @ new location          entities[index] = t;      } }  sf::renderwindow *graphicsdevice::getsfmlwindow() { 	return wwindow; }
could give possible cause what's causing error? can tell i'm new c++, other programming tips appreciated.

edit: when don't declare 'sf::image image;' local variable 'loadtexture(char *cname)' , instead declare private member of class, upon class being destroyed says displays error notifying me of heap corruption, instead of usual stack corruption notification. hope helps.

can give sample call loadtexture?

1 thing sets off alarm bells usage of char* if strings; e.g.

code:
ptextures[itex].get()->sname.c_str()==cname
checks pointer returned ptextures[itex].get()->sname.c_str() equal pointer cname (not strings equal!) - pretty unlikely case in practice

and

code:
ptextures[itexturecount].get()->sname = cname;
this stores pointer cname sname, might not want - if cname e.g. passed in local stack object function , function went out of scope, sname dangling pointer. (there plenty of other situations cause similar problem).

edit:

general points: when writing c++ apps, std::string preferred raw char*'s. also, many people prefer scope of variables minimal possible, means (at least) declared close point @ first used possible. e.g. in loadtexture, we'd have

code:
	for (unsigned int itex=0; itex<itexturecount; itex++)
instead of declaring itex @ top of block (assuming there no other references itex outside ... loop - didn't see @ quick glance )

also, purely subjective , stylistic choice - many people thoroughly loathe hungarian notation


Forum The Ubuntu Forum Community Ubuntu Specialised Support Development & Programming Programming Talk Stack corruption driving me insane


Ubuntu

Comments

Popular posts from this blog

How to change text Component easybook reloaded *newbee* - Joomla! Forum - community, help and support

After Effect warning: A problem occurred when processing OpenGL commands

Preconditions Failed. - Joomla! Forum - community, help and support