1

I've been toying with this code a guy on youtube attached to one of his tutorial videos... I've run into a few problems that I cant seem to get past... The current one is this 'EXC_BAD_ACCESS' error... From what I've researched briefly online these errors occur when you improperly use the stack and allocate memory to things that no longer exist or something like that... I just can't pinpoint what I'm doing wrong exactly... I've seen some troubleshooting done -- but nothing for xcode 5 yet

The error shows up in a class called 'cSprite.cpp':

// ~~~~~~~~~~~~~~~~~~~     cSprite.cpp      ~~~~~~~~~~~~~~~~~~~~~~~~~~~

#include "stdafx.h"
#include "cSprite.h"
//#include "gMain.h"
//#include <SDL2/SDL_main.h>
//#include <SDL2/SDL.h>
//#include "cSDL_Setup.h"

using namespace std;

void draw(SDL_Renderer, SDL_Texture, SDL_Rect);

cSprite::cSprite(SDL_Renderer* passed_renderer, string filePath, int x, int y, int w, int h)
{
    renderer = passed_renderer;

    //... image
    image = NULL;
    image = IMG_LoadTexture(renderer,filePath.c_str());

    // image error message
    if (image == NULL)
    {
        cout<<"Couldnt load image..."<<filePath.c_str()<<endl;
    }

    //image dimensions
    rect->x = x;            // ***** Error: Thread 1:EXC_BAD_ACCESS(code=EXC_1386_GPFLT)
    rect->y = y;
    rect->w = w;
    rect->h = h;

};

cSprite::~cSprite(void)
{
    SDL_DestroyTexture(image);
}

//get methods
//SDL_Rect* cSprite::getRect()
//{
//    return rect;
//}

//get methods
//SDL_Texture* cSprite::getImage()
//{
//    return image;
//}

void cSprite::draw()
{
    SDL_RenderCopy(renderer, image, NULL, rect);
}

... the line 'rect->x = x;'

gets the error I put beside it...but idk what else could be causing it... I was hoping someone could explain why EXC_BAD_ACCESS errors even occur... and/or where in the rest of my code it could be coming from...

here's my 3 other .cpp files

....

// ~~~~~~~~~~~~~~~~~~~~~~~~        gMain.cpp        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <iostream>
#include "stdafx.h"
#include "gMain.h"


using namespace std;

gMain::gMain(int passed_screenWidth, int passed_screenHeight)
{
    screenWidth = passed_screenWidth;
    screenHeight = passed_screenHeight;

    // quit boolean
    quit = false;

    // create instance of cSDL class
    csdl_setup = new cSDL_Setup(&quit, screenWidth, screenHeight);

    grass = new cSprite(csdl_setup->getRenderer(), "/Users/jamesbryant/Desktop/nuGame/nuGame/images.jpeg", screenWidth, screenHeight, screenWidth, screenHeight);

    bruce_Lee = new cSprite(csdl_setup->getRenderer(), "/Users/jamesbryant/Desktop/nuGame/nuGame/lee.bmp", 300, 300, 200, 200);


}

gMain::~gMain(void)
{
}

void gMain::gameLoop(void)
{
    // game loop logic
    while (!&quit && csdl_setup->getMainEvent() ->type != SDL_QUIT)
    {
        csdl_setup->begin();

        grass->draw();
        bruce_Lee->draw();


        csdl_setup->end();

    }
}

....

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cSDL_Setup.cpp ~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include "stdafx.h"
#include "cSDL_Setup.h"
//#include "gMain.h"

using namespace std;

cSDL_Setup::cSDL_Setup(bool* quit, int screenWidth, int screenHeight)
{
    // create window
    window = NULL;
    window = SDL_CreateWindow("rWDY_pWDR", 400, 400, screenWidth, screenHeight, SDL_WINDOW_RESIZABLE);

    // if window couldnt be created...
    if (window == NULL)
    {
        cout<<"Window couldnt be created..."<<endl;

        *quit = true;
        //exit(0);
    }

    //create renderer
    renderer = NULL;
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

    // initialize images
    mainEvent = new SDL_Event();

}

cSDL_Setup::~cSDL_Setup(void)
{
    SDL_DestroyWindow(window);
    SDL_DestroyRenderer(renderer);
    delete mainEvent;
}

//get methods
SDL_Renderer* cSDL_Setup::getRenderer()
{
    return renderer;
}

SDL_Event* cSDL_Setup::getMainEvent()
{
    return mainEvent;
}

void cSDL_Setup::begin()
{
    SDL_PollEvent(mainEvent);
    SDL_RenderClear(renderer);
}

void cSDL_Setup::end()
{
    SDL_RenderPresent(renderer);

}

....

// ~~~~~~~~~~~~~~~~~~~~~~~~~~ firstGame.cpp ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include "stdafx.h"
#include "cSDL_Setup.h"
//#include "gMain.h"

using namespace std;

cSDL_Setup::cSDL_Setup(bool* quit, int screenWidth, int screenHeight)
{
    // create window
    window = NULL;
    window = SDL_CreateWindow("rWDY_pWDR", 400, 400, screenWidth, screenHeight, SDL_WINDOW_RESIZABLE);

    // if window couldnt be created...
    if (window == NULL)
    {
        cout<<"Window couldnt be created..."<<endl;

        *quit = true;
        //exit(0);
    }

    //create renderer
    renderer = NULL;
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);

    // initialize images
    mainEvent = new SDL_Event();

}

cSDL_Setup::~cSDL_Setup(void)
{
    SDL_DestroyWindow(window);
    SDL_DestroyRenderer(renderer);
    delete mainEvent;
}

//get methods
SDL_Renderer* cSDL_Setup::getRenderer()
{
    return renderer;
}

SDL_Event* cSDL_Setup::getMainEvent()
{
    return mainEvent;
}

void cSDL_Setup::begin()
{
    SDL_PollEvent(mainEvent);
    SDL_RenderClear(renderer);
}

void cSDL_Setup::end()
{
    SDL_RenderPresent(renderer);

}

... here's what my cSprite.h file looks like right now:

#ifndef __game__cSprite__
#define __game__cSprite__
#pragma once

#include <iostream>
#include <SDL2/SDL_main.h>
#include <SDL2/SDL.h>

using namespace std;


class cSprite
{
public:
    cSprite(SDL_Renderer* passed_renderer, string filePath, int x, int y, int w, int h);
    ~cSprite(void);

    void draw();

private:
    SDL_Texture* image = NULL;

    SDL_Rect* rect = NULL;

    SDL_Renderer* renderer = NULL;

};

#endif /* defined(__game__cSprite__) */

1 Answers1

1

You didn't post your header for cSprite. However, I imagine that rect is an SDL_Rect*.

The function getting the error is cSprite::cSprite(), ie. the constructor. One of its duties is to initialize all of the class members to reasonable values.

However, I do not see any code that initializes rect to point to anything. The error you're currently getting suggests you're dereferencing a bum pointer, and that's consistent with this observation.

You either need to allocate an SDL_Rect to assign to rect, or you should change rect to just be SDL_Rect, not SDL_Rect*. If you make the latter change, then you will also need to change all of your rect-> to rect., and pass a pointer to rect in the SDL calls that require it (ie. SDL_RenderCopy(renderer, image, NULL, &rect);)

Joe Z
  • 17,413
  • 3
  • 28
  • 39