开发者

EXC_BAD_ACCESS on iPhone (C++) when accessing a variable inside method

开发者 https://www.devze.com 2023-03-06 14:20 出处:网络
I\'m making a port of a j2me game to iPhone using C++, and i have a strange problem. My C++ skills are not the best, i come from some years of Java development, and i haven\'t touched C++ for years. M

I'm making a port of a j2me game to iPhone using C++, and i have a strange problem. My C++ skills are not the best, i come from some years of Java development, and i haven't touched C++ for years. My problem is that i have a class member that it's assigned on constructor, but i got a EXC_BAD_ACCESS when i try to access this variable on a method of this class. I have surfed the web, and i can't find the problem, i hope that you can help me with this. Here are a modified version of the code:

GameCanvas.h

#include "Graphics.h"
#include "defs.h"

class GameCanvas {

Graphics* canvasGraphics;

public:

GameCanvas(void);

Graphics* getGraphics(void);

};

GameCanvas.cpp

#include <stdio.h>

#include "GameCanvas.h"

#include "Wrap-C-Interface.h"

GameCanvas::GameCanvas(void)
{
canvasGraphics = new Graphics();

// Sets up matrices and transforms for OpenGL ES
glMatrixMode(GL_PROJECTION); 
glLoadIdentity();
glViewport(0, 0, 320.0f, 480.0f);
glOrthof(0.0f, 320.0f,
         480.0f, 0.0f,
         -1.0f,   1.0f);

glMatrixMode(GL_TEXTURE);

glLoadIdentity();
glOrthof(0.0f, 512.0f*2,
         0.0f, 512.0f*2,
         -1.0f,   1.0f);

glMatrixMode(GL_MODELVIEW); 

// Clears the view with black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

// Enable use of the texture
glEnable(GL_TEXTURE_2D);
// Set a blending function to use
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
开发者_运维技巧// Enable blending
glEnable(GL_BLEND);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
}

Graphics* GameCanvas::getGraphics(void) 
{
    // Here canvasGraphics is no longer alive, i got an EXC_BAD_ACCESS
    return canvasGraphics;
}

Graphics.h

#include "defs.h"

#include "iGraphics.h"
#include "Image.h"

class Graphics 
{
public:
int test;

Graphics(void);

void setColor(int RGB);
void setColor(int red, int green, int blue);
void fillRect(int x, int y, int width, int height);

private:
Image* buffer;  
GLuint textureFrameBuffer;

};

Graphics.cpp

#include "Graphics.h"

#include "Wrap-C-Interface.h"

Graphics::Graphics(void)
{
test = 314;
buffer = Image::createImage(512, 512);

// create framebuffer
glGenFramebuffersOES(1, &textureFrameBuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);

// attach renderbuffer
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, buffer->tex2d->texture, 0);

// restore frame buffer
restoreFrameBuffer();
};

void Graphics::setColor(int red, int green, int blue) 
{
glColor4ub(red, green, blue, 255);
}

void Graphics::setColor(int RGB)
{
glColor4ub(RGB>>16&0xff, RGB>>8&0xff, RGB&0xff, 255);
}

void Graphics::fillRect(int x, int y, int width, int height)
{
GLshort vertices[] = {
    x,          y,
    x + width,  y,
    x,          y + height,
    x + width,  y + height, 
};
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

glVertexPointer(2, GL_SHORT, 0, vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// restore default state
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
}

EDITED:

I didn't mention on original post that it hangs calling getGraphics() of GameCanvas, any access to canvasGraphics inside getGraphics gives a EXC_BAD_ACCESS. One example, if i put this line after this Graphics object is instantiated on GameCanvas constructor, it works as expected:

canvasGraphics = new Graphics();
printf("canvasGraphics %i\n", canvasGraphics->test);

But this printf command on getGraphics method gives an EXC_BAD_ACCESS.

Graphics* GameCanvas::getGraphics(void) 
{
    // Here canvasGraphics is no longer alive, i got an EXC_BAD_ACCESS
    printf("canvasGraphics %i\n", canvasGraphics->test);
    return canvasGraphics;
}


Your problem could be here:

buffer = Image::createImage(512, 512);

I notice you don't check the return value. Is there any possibility that createImage would return NULL?


If you don't have a live Graphics object (I'm assuming you mean that either the constructor hasn't been called yet OR the object has been destroyed at the time this getGraphics() is called), then you're accessing junk memory if you're trying to reference a member data object of the canvasGraphics object (like canvasGraphics->test). So this is a perfectly legitimate exception.

You say you've come from the java world but this would be illegal in java also (except, you never know the exact lifetime of an object in java since you rely on GC to destroy the object).

0

精彩评论

暂无评论...
验证码 换一张
取 消