Sign in to follow this  

Why is C++ crashing on this?

This topic is 4714 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

All right... A Classes question:
class ResManager{
public:
	ResManager();
	~ResManager();

	GLuint loadTextureDisk(std::string, bool);
	GLuint loadTextureRAM(SDL_Surface*);
	void freeTexture(GLuint);
private:
	int numTextures;
	Uint32 GetPixel(SDL_Surface*, int, int);
};

ResManager::ResManager(){
	numTextures = 0;
}
(And some other functions, too much to post) From this class, I make a global instance (yeah... I know I should look into Singletons...), by including 'extern ResManager *rm;' at every file using it (in a header of course), and by putting 'ResManager *rm;' in the main file (outside the main function). I then initialize rm in my main method: 'rm = new ResManager();'. AFAIK, these are the necessary steps to make global variables. At some point in my program, I use this class (with rm->loadTextureDisk), and somewhere in this function call, 'numTextures++;' is done. On this, the app crashes with an acces violation. The watch-window states numTextures 'cannot be evaluated' inside the loadTextureDisk-function. And I'm sure the constructor runs fine (step-by-step debugging). So, what happens with my numTextures value along the way? Or did I miss something as big as an elephant here? (seems to happen frequently :-D) Thanks, -Amarth

Share this post


Link to post
Share on other sites
I have no idea why it scrashing without being able to look at the rest of ur program but i will say that if u KNOW u are only going to need 1 object of a particular class i would seriously suggest looking inton the Singleton Pattern.

ace

Share this post


Link to post
Share on other sites
There is not much more that I can give you... This I mostly 'borrowed' from other sites, and I do not know whether it works or not because of the crash :).

GLuint ResManager::loadTextureDisk(std::string file, bool repeat){
GLuint tex;

// Load the 'file' to SDL_Surface
SDL_Surface *img = NULL;
img = IMG_Load(file.c_str());
if(img == NULL)
errorLog->addLog("Unable to load texture from " + file + "\nThe error is: " + IMG_GetError());

// Build the texture from the surface
int dim = img->w * img->h * 4; //4 for RGBA
GLubyte *data;
data = (GLubyte*)malloc(sizeof(GLubyte) * dim);
if(!data)
errorLog->addLog("Unable to create a texture from " + file);

// Traverse trough surface and grab the pixels (from end to start!)
int pos = 0;
for(int y=(img->h-1); y>-1; y--) {
for(int x=0; x<img->w; x++) {
Uint8 r,g,b,a;
Uint32 color = GetPixel(img, x,y);

SDL_GetRGBA(color, img->format, &r,&g,&b,&a);

data[pos] = r; pos++;
data[pos] = g; pos++;
data[pos] = b; pos++;
data[pos] = a; pos++;
}
}

glGenTextures(1, &tex); // Generate texture ID
glBindTexture(GL_TEXTURE_2D, tex);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img->w, img->h, 0, GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE, data);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (repeat) ? GL_REPEAT : GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (repeat) ? GL_REPEAT : GL_CLAMP);

// Clean up and return the texture ID
free(data);
SDL_FreeSurface(img);

numTextures++;

return tex;
}


I inted to extend this a bit (make alpha optional etc), but it would be cool when it would work :).
It crashes on the 'numTextures++;' line, at the end.

-Amarth

Share this post


Link to post
Share on other sites
Well when u say it crashes on that line where u increment then i have no idea, sorry.

Are you absolutely sure it crashes there and not just before it?
Have you tried removing the line where u increment and making numTextures fixed for the purpose of testing?

One thing i ALWAYS try when im stuck is a clean and rebuild. This is just to make sure the error is relevent to all latest compilations. In Visual Studio if you have linked the code and are stepping through it to debug and u delete some code or comment above the error, the error can appear to be on a different line.

If you are still in trouble, send me the whole workspace and i'll havea look for you.

These are the only things i can think of.

ace

Share this post


Link to post
Share on other sites
It crashes on that line. It defenitely does. And I tried a couple of clean rebuilds, it didn't help. Commenting the line, and the program runs.
Perhaps I should omit that feature... Or implement it another way... But I'd still want to know what's going on :).
I'm off to sleep now... If you give me a way to contact you I could send the workspace. Or, if you'd prefer that, I can get it uploaded somewhere. But I really don't want to take too much of your time. It's not that urgent, after all :).

-Amarth

Share this post


Link to post
Share on other sites
Can you post the structure of your project and its initialization sequence? By initialization sequence I mean the instantiation of the ResManager and the usage of it there after until it crashes. What I suspect is that in the module where your program crashes the ResManager pointer is not the one that you have created in the main function. It might be a dangling pointer.

Cheers,

~Ajit

Share this post


Link to post
Share on other sites
That could be... But it's global after all... Lemme share the following methods (do'n care about the comments, it's Dutch. I type a lot to myself when programming :lol:):


//main.cpp
#include "GameWrapper.h"
#include "globals.h"
#include "error.h"

#include <sdl/sdl.h>
#include <stdio.h>
#include <stdlib.h>

#define UPDATEDELTA 25

Log *errorLog;
ResManager *rm;
bool globalRunning;

int main(int argc, char *argv[])
{
//init
errorLog = new Log();
rm = new ResManager();
GameWrapper *gw = new GameWrapper();

//voorfilmke, title screen etc (menu in loop?)

//game loop
//Uint32 count = SDL_GetTicks();
while(globalRunning){
gw->render();
gw->handleEvents();
gw->updateWorld(SDL_GetTicks());
}

delete gw;
delete rm;
delete errorLog;
return 0;
}
//end of file

//globals.h
//you'll never guess... the global variables! :shock:

#ifndef GLOBALS_H
#define GLOBALS_H

#include "error.h"
#include "resmanager.h"

extern Log *errorLog;
extern ResManager *rm;
extern bool globalRunning;

#endif //GLOBALS_H
//end of file

//part of gamewrapper.cpp
GameWrapper::GameWrapper(){
globalRunning = true;

testVal = 0;

errorLog->addLog("test");

readSettings();

ww = new WindowWrapper(settings->width, settings->heigth, settings->bpp, settings->videoFlags(), "FreeAlley", "icon.bmp");

testTex = rm->loadTextureDisk("alphatest.png",false);
}




On the last line, the code jumps to loadTextureDisk, and then it crashes on the numTextures++ line.
So, I'm (trying to) create a global *rm, and I'm using that in one of my other classes to make a texture. And that doesn't work.
I'm going to debug a bit more, perhaps I can get track of a bit more information.

*EDIT*
I got some more information:
When jumping into the GameWrapper constructor, the value of rm (in the watch window) first changes to 'cannot be evaluated', and then points to a different memory adress then it was doing before that jump. My other global variables don't do this. Why is this?

*EDIT 2*
It's not a 'cannot be evaluated', it's a 'variable needs stack frame' error. At the next line of code, it seems as if the pointer has been given a random memory adress.

-Amarth

[Edited by - Amarth on January 18, 2005 6:47:37 AM]

Share this post


Link to post
Share on other sites
Are you sure rm has been instantiated when you try to use it, ie rm = new ResManager(); ? numTextures++ is the first use of the implicit 'this' in that function (it actually looks like 'this->numTextures++;'), so rm must not point to a valid instance of ResManager.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kibble
Are you sure rm has been instantiated when you try to use it, ie rm = new ResManager(); ? numTextures++ is the first use of the implicit 'this' in that function (it actually looks like 'this->numTextures++;'), so rm must not point to a valid instance of ResManager.


Yes, it's instantiated in the main method *before* the constructor of GameWrapper, so that should be OK. I start to suspect some error in my global variables code.

*EDIT*
The CXX0069 (variable needs stack frame) error seems to suggest some scoping trouble... Can someone tell me what's wrong with my global variables?

*EDIT2*
Well... I *think* I solved it with a Singleton... It works now, anyway :). Thanks all for reading this and trying to help.

-Amarth

[Edited by - Amarth on January 18, 2005 10:56:55 AM]

Share this post


Link to post
Share on other sites

This topic is 4714 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this