Binary Tree Template Program

Crash at return statement with some classes

Page 1 of 1

1 Replies - 1631 Views - Last Post: 02 February 2009 - 08:41 PM Rate Topic: -----

#1 Linkowiezi  Icon User is offline

  • D.I.C Regular

Reputation: 58
  • View blog
  • Posts: 316
  • Joined: 07-October 08

Binary Tree Template Program

Post icon  Posted 02 February 2009 - 12:16 PM

Well, I'm just wondering why my program crashes at the return when I use my SPRITE class but not my other test class.

It seems to work fine, until it reaches the the return statement, then it crashes.
I can access the nodes and use the functions within the sprite class if I try to do it before it reaches the end of the addNode function.

Anyone have any idea what might be wrong?

I have a *.zip and a *.rar file(with the same content)(apparently this site doesn't allow *.rar attachments) attached for anyone who rather download the whole thing.

PS, for the SPRITE class to work you'll need the SDL library available -> HERE <-

For those of you who rather look at the code here in the forum without downloading anything here it goes:

main.cpp
/***********************************************************************************************************************
    Definitions, Includes & Namespaces
***********************************************************************************************************************/
#define UINT unsigned int
#include <iostream>
#include "sprite.h"
#include "tree_template.h"
using namespace std;
typedef UINT uint;
//- Definitions, Includes & Namespaces ---------------------------------------------------------------------------------


/**********************************
    TEST CLASS, DELETE THIS!!!
**********************************/
class TestClass{
  int x;
  public:
    TestClass() : x(0) {}
    void setX(int newX){ x=newX; }
    int  getX(){ return x; }
};
//typedef TestClass Data;
//- TEST CLASS, DELETE THIS!!! ----


std::string modString(std::string str){
  string newString;
  uint usable = 0;
  uint firstUsable = 0;
  for( uint i = 0; i < str.length(); i++){
    switch(str[i]){
      case '/':
        firstUsable = i+1;
        usable = 0;
        break;
      case '.':
        i = str.length();
        break;
      default:
        usable++;
        break;
    }
  }
  char cha[usable+1];
  for( uint i = 0; i < usable; i++ )
    cha[i] = str[i+firstUsable];
  cha[usable] = '\0';
  
  newString = cha;
  
  return newString;
}

/***********************************************************************************************************************
    Main function
***********************************************************************************************************************/
int main( int argc, char *argv[] ){
  cout << "START OF PROGRAM!" << endl;
  
cout << "1" << endl;
  
  const uint N = 5;
  char cStr[N];
  TestClass test;
  test.setX(3);
  
  TreeTemplate<TestClass> testTree;
  if(testTree.addNode(test, "3"))
    cout << "This should happen!" << endl;
  else
    cout << "This should not happen, but this is still better than nothing..." << endl;
  
  for(uint i = 0; i < N; i++){
    itoa(i, cStr, 10);
    if(testTree.addNode(test,cStr))
      cout << "This should happen!" << endl;
    else
      cout << "This should not happen, but this is still better than nothing..." << endl;
  }
  testTree.traverseNode();
  
  SPRITE firstSprite;
  SPRITE *secondSprite;
  
cout << "2" << endl;
  
  cout << endl;
  TreeTemplate<SPRITE> tree;
  
cout << "3" << endl;
  
  cout << endl;
  SDL_Surface *screen;
cout << "3.5" << endl;
  std::string str;
  cout << "3.6" << endl;
  const uint WIDTH = 1024, HEIGHT = 768;
  cout << "3.7" << endl;
  uint MAXSPRITES = 2, width, height, startX, startY;
  cout << "3.8" << endl;
  if( SDL_Init( SDL_INIT_TIMER | SDL_INIT_VIDEO ) < 0 )
  {
      std::cerr << "During InOut::initWindow(); Unable to initialize SDL: " << SDL_GetError() << std::endl;
      exit( 1 );
  }
  
  atexit( SDL_Quit );
  
  //  Set title bar
  SDL_WM_SetCaption("Tree Test Program", "TTP");
  
  //  Set video mode
  screen = SDL_SetVideoMode( WIDTH, HEIGHT, 32, SDL_HWSURFACE | SDL_DOUBLEBUF );
  if( screen == NULL ){
      std::cerr << "During InOut::initWindow(); Unable to set " << WIDTH << "x" << HEIGHT << " video: " << SDL_GetError() << std::endl;
      exit( 1 );
  }
  cout << "3.9" << endl;
  Uint32 transColor = SDL_MapRGB(screen->format, 255, 0, 255);
cout << "4" << endl;
  for(uint i = 0; i < MAXSPRITES; i++ ){
    cout << "5" << endl;
    switch(i){
      case 0: str = "Art/UI/BG.bmp"; width=1024; height=768; startX=0; startY=0; break;
      case 1: str = "Art/UI/UI_Bar.bmp"; width=1024; height=168; startX=0; startY=600; break;
      default: std::cerr<<"initSprites(); Trying to load to many sprites: MAX="<<MAXSPRITES<<" i="<<i<<std::endl; exit(1); break;
    }
    cout << "6" << endl;
    if(!firstSprite.InitSprite( str, startX, startY, width, height, WIDTH, HEIGHT, false, 0, 0, 0, true, transColor, screen )){
      std::cerr << "Error initializing sprite" << std::endl;
      exit(1);
    }

    cout << "7" << endl;
    str = modString(str);
    cout<<endl<<endl<<endl<< "This is the new modified string: '" << str << "'" <<endl<<endl<<endl;
    if(tree.addNode(firstSprite, str))
      cout << "This should happen!" << endl;
    else
      cout << "This should not happen, but this is still better than nothing..." << endl;
    cout << "8" << endl;
  }
  
  cout << endl;
  for(uint i = 0; i < MAXSPRITES+1; i++ ){
    cout<<"if(tree.getData("<<str<<") != NULL)"<<endl;
    if((secondSprite=tree.getData(str)) != NULL){
      cout<<"  if(tree.getData("<<str<<") != NULL) was true"<<endl;
    }
    else
      cout<<"  if(tree.getData("<<str<<") != NULL) was false"<<endl;
  }
  
  cout << "END OF PROGRAM!" << endl << endl;
  return 0;
}
//- Main function ------------------------------------------------------------------------------------------------------


tree_template.h
/***********************************************************************************************************************
    Definitions, Includes & Namespaces
***********************************************************************************************************************/
#include <iostream>
#include <string>
using namespace std;
//- Definitions, Includes & Namespaces ---------------------------------------------------------------------------------


#ifndef TREE_TEMPLATE_H_
#define TREE_TEMPLATE_H_


template<class Data>
class TreeTemplate;
/**********************************************************************************************************************/
template<class Data>
class TreeNode{
/**********************************************************************************************************************/
  friend class TreeTemplate<Data>;
  TreeNode *left, *right;
  Data data;
  std::string id;
  TreeNode(Data newData, std::string newId){ cout << "new TreeNode..." << endl; data=newData; id=newId; left=NULL; right=NULL; }
  ~TreeNode(){ cout << "~TreeNode()" << endl; }
};
//- TreeNode -----------------------------------------------------------------------------------------------------------


/**********************************************************************************************************************/
template<class Data>
class TreeTemplate{
/**********************************************************************************************************************/
/***********************************************************************************************************************
    Variables
***********************************************************************************************************************/
  TreeNode<Data> *first;
//- Variables ----------------------------------------------------------------------------------------------------------

  public:
/***********************************************************************************************************************
    Constructors
***********************************************************************************************************************/
    TreeTemplate() : first(NULL) { cout << "new TreeTemplate..." << endl; }
//- Constructors -------------------------------------------------------------------------------------------------------


/***********************************************************************************************************************
    Destructors
***********************************************************************************************************************/
    ~TreeTemplate(){
      cout << "~TreeTemplate()..." << endl;
      traverseNode(first);
      cout << "end TreeTemplate..." << endl;
    }
    
    void traverseNode(){
      cout << "TraverseNode()..." << endl;
      traverseNode(first);
      cout << "end TraverseNode()" << endl;
    }
    
  private:
    void traverseNode(TreeNode<Data> *currentNode){
      cout << "traverseNode(TreeNode<Data>)..." << endl;
      cout << "  if(currentNode != NULL)" << endl;
      if(currentNode != NULL ){
        cout << "    if(currentNode->left != NULL)" << endl;
        if(currentNode->left != NULL)
          traverseNode(currentNode->left);
        cout << "    if(currentNode->right != NULL)" << endl;
        if(currentNode->right != NULL)
          traverseNode(currentNode->right);
        cout << "    Deleting node with id: " << currentNode->id << endl;
        delete(currentNode);
      }
      else
        cout << "  false" << endl;
      cout << "end traverseNode(TreeNode<Data>)..." << endl;
    }
  public:
//- Destructors --------------------------------------------------------------------------------------------------------


/***********************************************************************************************************************
    Set functions
***********************************************************************************************************************/
    //  Add Node
    bool addNode(Data newData, std::string newId){
      cout << "addNode(Data, string)..." << endl;
      TreeNode<Data> *newNode, *tempNode = first;
      newNode = new TreeNode<Data>(newData, newId);
      
      cout << "  if(first == NULL)" << endl;
      if(first == NULL){
        cout << "    true" << endl;
        first = newNode;
      }
      else{
        cout << "  else" << endl;
        bool match = false;
        cout << "    while(noMatch)" << endl;
        while(!match){
          cout << "      if(tempNode != NULL)" << endl;
          if(tempNode != NULL){
            cout << "        if(tempNode->id == newId)" << endl;
            if(tempNode->id == newId){
              cout << "          true" << endl;
              match = true;
            }
            else{
              cout << "          false" << endl;
              cout << "          if(newId < tempNode->id)" << endl;
              if(newId < tempNode->id){
                cout << "            if(tempNode->left != NULL)" << endl;
                if(tempNode->left != NULL){
                  cout  << "              true" << endl;
                  tempNode = tempNode->left;
                }
                else{
                  cout  << "              false" << endl;
                  break;
                }
              }
              else{
                cout << "            if(tempNode->right != NULL)" << endl;
                if(tempNode->right != NULL){
                  cout  << "              true" << endl;
                  tempNode = tempNode->right;
                }
                else{
                  cout  << "              false" << endl;
                  break;
                }
              }
            }
          }
          else
            cout << "        false" << endl;
        }
        if(!match){
          cout << "      no match" << endl;
          cout << "      if(newId < tempNode->id)" << endl;
          if(newId < tempNode->id){
            cout << "        true" << endl;
            tempNode->left = newNode;
          }
          else{
            cout << "        false" << endl;
            tempNode->right = newNode;
          }
        }
        else
          cout << "      found match" << endl;
      }
      cout << "end addNode(Data, string)..." << endl;
      
      cout << newNode->id << endl;
      
      cout << "All is fine untill return statement?" << endl;
      return true;
    }
//- Set functions ------------------------------------------------------------------------------------------------------


/***********************************************************************************************************************
    Get functions
***********************************************************************************************************************/
    //  Get node, without start node
    TreeNode<Data> *getNode(std::string id){
      cout << "getNode(string)" << endl;
      TreeNode<Data> *temp = first;
      temp = getNode(id, temp);
      cout << "end getNode(string)" << endl;
      return temp;
    }
    //  Get node, and start searching from here
  private:
    TreeNode<Data> *getNode(std::string id, TreeNode<Data> *node){
      TreeNode<Data> *temp = node;
      cout << "getNode(id, TreeNode<Data>)" << endl;
      cout << "id=" << id << endl;
      cout << "  if(id < temp->id)" << endl;
      if(id < temp->id){
        cout << "    true" << endl;
        cout << "    if(temp->left != NULL)" << endl;
        if(temp->left != NULL){
          cout << "      true" << endl;
          temp = getNode(id, temp->left);
        }
        else{
          cout << "      false, returning NULL" << endl;
          return NULL;
        }
      }
      else if(id > temp->id){
        cout << "    second true" << endl;
        cout << "    if(temp->right != NULL)" << endl;
        if(temp->right != NULL){
          cout << "      true" << endl;
          temp = getNode(id, temp->right);
        }
        else{
          cout << "      false, returning NULL" << endl;
          return NULL;
        }
      }
      else
        cout << "    false" << endl;
      if(temp != NULL)
        cout << "returning temp->id: " << temp->id << endl;
      else
        cout << "returning NULL" << endl;
      cout << "end getNode(string, TreeNode<Data>)" << endl;
      return temp;
    }
  public:
    
    //  Get data from a node
    Data *getData(std::string id){
      TreeNode<Data> *temp;
      temp = getNode(id);
      if(temp != NULL){
        cout << "returning data from node with id=" << temp->id << endl;
        return &temp->data;
      }
      else
        return NULL;
    }
//- Get functions ------------------------------------------------------------------------------------------------------
};
//- TreeTemplate -------------------------------------------------------------------------------------------------------

#endif
//- TREE_TEMPLATE_H_ ---


sprite.h
#include <iostream>
#include <SDL/SDL.h>

using namespace std;

#ifndef __SPRITE__
#define __SPRITE__

class SPRITE
{
    private:
        //  Sprite variables
        
        //  Used to check if the sprite built and ready to use
        bool sBuilt;
        
        //  SDL_Surfaces
        SDL_Surface *image, *screen;
        
        //  The rectangles used for drawing
        SDL_Rect rcSprite, rcScr;
        
        //  Stores the pathname and filename for the sprite image
        char imgPath[255];
        
        //  Positions
        int xPos, yPos;
        int xPosOld, yPosOld;   //  ...are they ever used?
        
        //  Sprite size
        int xSize, ySize;
        
        //  Window size and sprite boundary
        int wSizeX, wSizeY;
        bool wBoundary;         //  is the sprite limited to stay inside the window?
                
        //  Speed
        int mSpeed;
        int minSpeed, maxSpeed;
        
        //  Transparency
        bool isTrans;
        Uint32 colorkey;
    
        //  Animation
        bool isAnimated;
        int nSets, set;         //  Number of animation sets
        int nFrames, frame;     //  Number of frames for each set
        int animPause;          //  Paustime before switcing to a new frame
        
    public:
        //  Constructors
        SPRITE();               //  Use this in combination with the "InitSprite(...)" functions
        
        //  Destructor
        ~SPRITE();
        
        //  Initialization of the sprites can be done with these functions
        bool InitSprite( string filename, int width, int height, bool transparent, Uint32 colKey, SDL_Surface *scr );    //  Useful for backgrounds
        bool InitSprite( string filename, int width, int height, int wWidth, int wHeight, int boundary, int speed, int sMIN, int sMAX, bool transparent, Uint32 colKey, SDL_Surface *scr );                                                            //  Useful for sprites without starting position nor animation
        bool InitSprite( string filename, int startX, int startY, int width, int height, int wWidth, int wHeight, int boundary, int speed, int sMIN, int sMAX, bool transparent, Uint32 colKey, SDL_Surface *scr );                                    //  Useful for sprites with starting position but not animation
        bool InitSprite( string filename, int sets, int frames, int pause, int width, int height, int wWidth, int wHeight, int boundary, int speed, int sMIN, int sMAX, bool transparent, Uint32 colKey, SDL_Surface *scr );                           //  Useful for sprites without starting position but with animation
        bool InitSprite( string filename, int startX, int startY, int sets, int frames, int pause, int width, int height, int wWidth, int wHeight, int boundary, int speed, int sMIN, int sMAX, bool transparent, Uint32 colKey, SDL_Surface *scr );   //  Useful for sprites with both starting position and animation
        
        //  Functions associated with building the sprite and checking if it can be used
        bool IsBuilt();                     //  Returns wether the sprite is ready to use or not
        bool InitIMG( string filename );    //  Returns false if there is an error during the initialization
        void TryBuild( string filename );   //  Tries to build the sprite
        
        //  Functions associated with drawing the sprite
        void DrawSprite();                          //  Draws the sprite onto the screen
        void DrawSpriteOverride();                  // Draws the sprite even off screen
        bool OnScreen();                            //  Checks if the sprite is on screen
        
        //  Functions associated with animating the sprite
        void AnimateS( string PrevNext );           //  Use the previous/next set with the same frame, or the first set with the same frame if it's already at the last set and next is used, or the last set with the same frame if it's already at the first one and prev is used
        void AnimateF( string PrevNext );           //  Use the previous/next frame in the same set, or the first frame in the same set if it's already at the last frame and next is used, or the last frame in the same set if it's already at the first one and prev is used
        void AnimateS( int newSet );                //  Jumps to the sprcific set and uses the same frame
        void AnimateF( int newFrame );              //  Jumps to the specific frame in the same set
        void AnimateSF( int newSet, int newFrame ); //  Use a specific set and frame for the animation
        
        //  Functions associated with moving the sprite
        void BoundaryCorrection();          //  If the sprite doesn't have to stay within the boundary of the window this function will correct the SDL_Rect cordinates to their correct values
        bool MoveSprite( string dir );      //  Moves the sprite in the designated direction
        void SetSpritePos( int x, int y );  //  Moves the sprites upper left corner to this exact position
        
        //  Functions that will let you get some sprite variables
        SDL_Rect getRect();                 //  Returns the SDL_Rectangle of the sprite
};

#endif


sprite.cpp
#include "sprite.h"

////////////////////////////////////////////////////////////////////////////////
//  Constructors
////////////////////////////////////////////////////////////////////////////////

//  Use this in combination with the "InitSprite(...)" functions
SPRITE::SPRITE()
{
    //  Give variables a starting value
    image = NULL, screen = NULL;
    xPos = 0, yPos = 0;
    xPosOld = 0, yPosOld = 0;
    xSize = 0, ySize = 0;
    wSizeX = 0, wSizeY = 0;
    wBoundary = false;
    mSpeed = 0;
    minSpeed = 0, maxSpeed = 0;
    isTrans = false;
    
    //  The sprite is not built at this stage
    sBuilt = false;
}

////////////////////////////////////////////////////////////////////////////////
//  Destructor
////////////////////////////////////////////////////////////////////////////////

SPRITE::~SPRITE()
{
    SDL_FreeSurface(image);
}

////////////////////////////////////////////////////////////////////////////////
//  Initialization of the sprites can be done with these functions
////////////////////////////////////////////////////////////////////////////////

//  Useful for backgrounds
bool SPRITE::InitSprite( string filename, int width, int height, bool transparent, Uint32 colKey, SDL_Surface *scr )
{
    //  Give variables a starting value
    
    //  SDL_Surfaces
    image = NULL;
    screen = scr;
    
    //  The rectangles used for drawing
    rcSprite.x = 0;
    rcSprite.y = 0;
    
    rcScr.x = 0;
    rcScr.y = 0;
    rcScr.w = width;
    rcScr.h = height;
    
    //  Positions
    xPos = 0, yPos = 0;
    xPosOld = 0, yPosOld = 0;
    
    //  Sprite size
    xSize = width, ySize = height;
    
    //  Window size
    wSizeX = width, wSizeY = height;
    wBoundary = false;
    
    //  Speed
    mSpeed = 0;
    minSpeed = 0, maxSpeed = 0;
    
    //  Transparency
    isTrans = transparent;
    colorkey = colKey;
    
    //  Animation
    isAnimated = false;
    nSets = 0, set = 0;
    nFrames = 0, frame = 0;
    animPause = 0;
    
    //  The sprite is not built at this stage
    sBuilt = false;
    
    //  Now we try to build the sprite
    TryBuild( filename );
    
    return sBuilt;
}

//  Useful for sprites without starting position nor animation
bool SPRITE::InitSprite( string filename, int width, int height, int wWidth, int wHeight, int boundary, int speed, int sMIN, int sMAX, bool transparent, Uint32 colKey, SDL_Surface *scr )
{
    //  Give variables a starting value
    
    //  SDL_Surfaces
    image = NULL;
    screen = scr;
    
    //  The rectangles used for drawing
    rcSprite.x = 0;
    rcSprite.y = 0;
    
    rcScr.x = 0;
    rcScr.y = 0;
    rcScr.w = width;
    rcScr.h = height;
    
    //  Positions
    xPos = 0, yPos = 0;
    xPosOld = 0, yPosOld = 0;
    
    //  Sprite size
    xSize = width, ySize = height;
    
    //  Window size
    wSizeX = wWidth; wSizeY = wHeight;
    wBoundary = boundary;
    
    //  Speed
    mSpeed = speed;
    minSpeed = sMIN, maxSpeed = sMAX;
    
    if( mSpeed < minSpeed ) mSpeed = minSpeed;
    else if( mSpeed > maxSpeed ) mSpeed = maxSpeed;
    
    //  Transparency
    isTrans = transparent;
    colorkey = colKey;
    
    //  Animation
    isAnimated = false;
    nSets = 0, set = 0;
    nFrames = 0, frame = 0;
    animPause = 0;
    
    //  The sprite is not built at this stage
    sBuilt = false;
    
    //  Now we try to build the sprite
    TryBuild( filename );
    
    return sBuilt;
}

//  Useful for sprites with starting position but no animation
bool SPRITE::InitSprite( string filename, int startX, int startY, int width, int height, int wWidth, int wHeight, int boundary, int speed, int sMIN, int sMAX, bool transparent, Uint32 colKey, SDL_Surface *scr )
{
    //  Give variables a starting value
    
    //  SDL_Surfaces
    image = NULL;
    screen = scr;
    
    //  The rectangles used for drawing
    rcSprite.x = startX;
    rcSprite.y = startY;
    
    rcScr.x = 0;
    rcScr.y = 0;
    rcScr.w = width;
    rcScr.h = height;
    
    //  Positions
    xPos = startX, yPos = startY;
    xPosOld = startX, yPosOld = startY;
    
    //  Sprite size
    xSize = width, ySize = height;
    
    //  Window size
    wSizeX = wWidth; wSizeY = wHeight;
    wBoundary = boundary;
    
    //  Speed
    mSpeed = speed;
    minSpeed = sMIN, maxSpeed = sMAX;
    
    if( mSpeed < minSpeed ) mSpeed = minSpeed;
    else if( mSpeed > maxSpeed ) mSpeed = maxSpeed;
    
    //  Transparency
    isTrans = transparent;
    colorkey = colKey;
    
    //  Animation
    isAnimated = false;
    nSets = 0, set = 0;
    nFrames = 0, frame = 0;
    animPause = 0;
    
    //  The sprite is not built at this stage
    sBuilt = false;
    
    //  Now we try to build the sprite
    TryBuild( filename );
    
    return sBuilt;
}

//  Useful for sprites without starting position but with animation
bool SPRITE::InitSprite( string filename, int sets, int frames, int pause, int width, int height, int wWidth, int wHeight, int boundary, int speed, int sMIN, int sMAX, bool transparent, Uint32 colKey, SDL_Surface *scr )
{
    //  Give variables a starting value
    
    //  SDL_Surfaces
    image = NULL;
    screen = scr;
    
    //  The rectangles used for drawing
    rcSprite.x = 0;
    rcSprite.y = 0;
    
    rcScr.x = 0;
    rcScr.y = 0;
    rcScr.w = width;
    rcScr.h = height;
    
    //  Positions
    xPos = 0, yPos = 0;
    xPosOld = 0, yPosOld = 0;
    
    //  Sprite size
    xSize = width, ySize = height;
    
    //  Window size
    wSizeX = wWidth; wSizeY = wHeight;
    wBoundary = boundary;
    
    //  Speed
    mSpeed = speed;
    minSpeed = sMIN, maxSpeed = sMAX;
    
    if( mSpeed < minSpeed ) mSpeed = minSpeed;
    else if( mSpeed > maxSpeed ) mSpeed = maxSpeed;
    
    //  Transparency
    isTrans = transparent;
    colorkey = colKey;
    
    //  Animation
    isAnimated = true;
    nSets = sets, set = 0;
    nFrames = frames, frame = 0;
    animPause = pause;
    
    //  The sprite is not built at this stage
    sBuilt = false;
    
    //  Now we try to build the sprite
    TryBuild( filename );
    
    return sBuilt;
}

//  Useful for sprites with both starting position and animation
bool SPRITE::InitSprite( string filename, int startX, int startY, int sets, int frames, int pause, int width, int height, int wWidth, int wHeight, int boundary, int speed, int sMIN, int sMAX, bool transparent, Uint32 colKey, SDL_Surface *scr )
{
    //  Give variables a starting value
    
    //  SDL_Surfaces
    image = NULL;
    screen = scr;
    
    //  The rectangles used for drawing
    rcSprite.x = startX;
    rcSprite.y = startY;
    
    rcScr.x = 0;
    rcScr.y = 0;
    rcScr.w = width;
    rcScr.h = height;
    
    //  Positions
    xPos = startX, yPos = startY;
    xPosOld = startX, yPosOld = startY;
    
    //  Sprite size
    xSize = width, ySize = height;
    
    //  Window size
    wSizeX = wWidth; wSizeY = wHeight;
    wBoundary = boundary;
    
    //  Speed
    mSpeed = speed;
    minSpeed = sMIN, maxSpeed = sMAX;
    
    if( mSpeed < minSpeed ) mSpeed = minSpeed;
    else if( mSpeed > maxSpeed ) mSpeed = maxSpeed;
    
    //  Transparency
    isTrans = transparent;
    colorkey = colKey;
    
    //  Animation
    isAnimated = true;
    nSets = sets, set = 0;
    nFrames = frames, frame = 0;
    animPause = pause;
    
    //  The sprite is not built at this stage
    sBuilt = false;
    //  Now we try to build the sprite
    TryBuild( filename );
    
    return sBuilt;
}

////////////////////////////////////////////////////////////////////////////////
//  Functions associated with building the sprite
//  and checking wether it is ready to use
////////////////////////////////////////////////////////////////////////////////

//  Returns wether the sprite is ready to use or not
bool SPRITE::IsBuilt()
{
    if( !sBuilt ) printf( "%s is not built correctly\n", imgPath );
    
    return sBuilt;
}

//  Returns false if there is an error during the initiaization process
bool SPRITE::InitIMG( string filename )
{
    bool result = true;
    SDL_Surface *temp;
    
    //  Set the image pathname for the sprite image
    for( unsigned int c = 0; c < filename.length(); c++ ) imgPath[c] = filename[c];
    imgPath[filename.length()] = '\0';
    
    //  Try to load the pictures
    temp = SDL_LoadBMP( imgPath );
    
    //  If a picture couldn't be loaded, print it to stdout.txt
    if( temp == NULL )
    {
        result = false;
        printf( "Unable to load '%s'\n", imgPath );
    }
    //  Else, do the color keying
    else
    {
        if     ( !isTrans ) SDL_SetColorKey( temp, 0, SDL_MapRGB( temp->format, 0, 0, 0 ) );
        else if( colorkey != 0 ) SDL_SetColorKey( temp, SDL_SRCCOLORKEY, colorkey );
        else
        {
            result = false;
            printf( "Keycoloring error with image '%s'\n", imgPath );
        }
    }
    //  If all went well we display the image format from temp in the sprite
    if( result == true ) image = SDL_DisplayFormat( temp );
    //  Then we free temp
    SDL_FreeSurface( temp );
    
    //  And finaly return the result
    return result;
}

//  Tries to build the sprite
void SPRITE::TryBuild( string filename )
{
    //  First off we try to load the image
    if( !InitIMG( filename ) )
    {
        sBuilt = false;
    }
    //  Then we check that some important variables are set correctly
    else if( image == NULL   ||
             screen == NULL  ||
             xSize <= 0      ||
             ySize <= 0      ||
             wSizeX <= 0     ||
             wSizeY <= 0     )
    {
        sBuilt = false;
    }
    else sBuilt = true;
}

////////////////////////////////////////////////////////////////////////////////
//  Functions associated with drawing the sprite
////////////////////////////////////////////////////////////////////////////////

// Draws the sprite onto the screen
void SPRITE::DrawSprite()
{
    if( OnScreen() )
    {
        BoundaryCorrection();
        SDL_BlitSurface( image, &rcScr, screen, &rcSprite );
    }
}


// Draws the sprite even off screen
void SPRITE::DrawSpriteOverride()
{
    BoundaryCorrection();
    SDL_BlitSurface( image, &rcScr, screen, &rcSprite );
}

//  Checks if the sprite is on screen
bool SPRITE::OnScreen()
{
    if( (xPos + xSize) < 0  ||
         xPos > wSizeX      ||
        (yPos + ySize) < 0  ||
         yPos > wSizeY      )
    {
        return false;
    }
    else return true;
}

////////////////////////////////////////////////////////////////////////////////
//  Functions associated with animating the sprite
////////////////////////////////////////////////////////////////////////////////

//  Use the previous/next set with the same frame,
//  or the first set with the same frame if it's already at the last set and next is used,
//  or the last set with the same frame if it's already at the first set and prev is used
void SPRITE::AnimateS( string PrevNext )
{
    bool result = true;
    
    if( PrevNext == "PREV" ) set--;
    else if( PrevNext == "NEXT" ) set++;
    else
    {
        result = false;
        cout << "Error with animation! Unknown command: " << PrevNext << endl;
    }
    
    if( result == true )
    {
        if( set == nSets )  set = 0;
        else if( set < 0 ){ set = nSets-1; if( set < 0 ) set = 0; }
        
        rcScr.y = (ySize * set);
    }
}

//  Use the previous/next frame in the same set,
//  or the first frame in the same set if it's already at the last frame and next is used,
//  or the last frame in the same set if it's already at the first frame and prev is used
void SPRITE::AnimateF( string PrevNext )
{
    bool result = true;
    
    if( PrevNext == "PREV" ) frame--;
    else if( PrevNext == "NEXT" ) frame++;
    else
    {
        result = false;
        cout << "Error with animation! Unknown command: " << PrevNext << endl;
    }
    
    if( result == true )
    {
        if( frame == nFrames ) frame = 0;
        else if( frame < 0 ){  frame = nFrames-1; if( frame < 0 ) frame = 0; }
        
        rcScr.x = (xSize * frame);
    }
}

//  Jumps to the sprcific set and uses the same frame
void SPRITE::AnimateS( int newSet )
{
    if( newSet <= nSets && newSet >= 0 )
    {
        set = newSet;
        rcScr.y = (ySize * set);
    }
    else printf( "Error with animation! Set: %i\n", newSet );
}

//  Jumps to the specific frame in the same set
void SPRITE::AnimateF( int newFrame )
{
    if( newFrame <= nFrames && newFrame >= 0 )
    {
        frame = newFrame;
        rcScr.x = (xSize * frame);
    }
    else printf( "Error with animation! Frame: %i\n", newFrame );
}

//  Use a specific set and frame for the animation
void SPRITE::AnimateSF( int newSet, int newFrame )
{
    if( newSet   <= nSets   && newSet   >= 0  &&
        newFrame <= nFrames && newFrame >= 0  )
    {
        set = newSet;
        frame = newFrame;
        
        rcScr.y = (ySize * set);
        rcScr.x = (xSize * frame);
    }
    else printf( "Error with animation! Set: %i, Frame: %i\n", newSet, newFrame );
}

////////////////////////////////////////////////////////////////////////////////
//  Functions associated with moving the sprite
////////////////////////////////////////////////////////////////////////////////

//  If the sprite doesn't have to stay within the boundary of the window
//  this function will correct the SDL_Rect cordinates to their correct values
void SPRITE::BoundaryCorrection()
{
    if( wBoundary == true)
    {
        if( xPos < 0 ) xPos = 0;
        else if( (xPos + xSize) > wSizeX ) xPos = wSizeX - xSize;
        
        if( yPos < 0 ) yPos = 0;
        else if( (yPos + ySize) > wSizeY ) yPos = wSizeY - ySize;
    }
    
    if( rcSprite.x != xPos ) rcSprite.x = xPos;
    if( rcSprite.y != yPos ) rcSprite.y = yPos;
}

//  Moves the sprite in the designated direction
bool SPRITE::MoveSprite( string dir )
{
    bool result = true;
    
    if     ( dir == "NORTH" )
    {
        yPos -= mSpeed;
    }
    else if( dir == "SOUTH" )
    {
        yPos += mSpeed;
    }
    else if( dir == "WEST" )
    {
        xPos -= mSpeed;
    }
    else if( dir == "EAST" )
    {
        xPos += mSpeed;
    }
    else if( dir == "NORTHWEST" )
    {
        yPos -= mSpeed;
        xPos -= mSpeed;
    }
    else if( dir == "NORTHEAST" )
    {
        yPos -= mSpeed;
        xPos += mSpeed;
    }
    else if( dir == "SOUTHWEST" )
    {
        yPos += mSpeed;
        xPos -= mSpeed;
    }
    else if( dir == "SOUTHEAST" )
    {
        yPos += mSpeed;
        xPos += mSpeed;
    }
    else result = false;
    
    return result;
}

//  Moves the sprites upper left corner to this exact position
void SPRITE::SetSpritePos( int x, int y )
{
    xPos = x;
    yPos = y;
}

////////////////////////////////////////////////////////////////////////////////
//  Functions that will let you get some sprite variables
////////////////////////////////////////////////////////////////////////////////

//  Returns the SDL_Rectangle of the sprite
SDL_Rect SPRITE::getRect()
{
    return rcSprite;
}


There are quite some debugging messages everywhere but I have no idea what I'm missing here to get this fatal crash, I'd be really happy if anyone could help me solve this problem.

Attached File(s)


This post has been edited by Linkowiezi: 02 February 2009 - 01:02 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Binary Tree Template Program

#2 perfectly.insane  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 70
  • View blog
  • Posts: 644
  • Joined: 22-March 08

Re: Binary Tree Template Program

Posted 02 February 2009 - 08:41 PM

The issue is more than likely how your SPRITE class is handling copies of itself. The addNode function takes in an item of the given type by value, which means that all variables are copied verbatim. This includes any pointer variables. Since the SPRITE class releases the resources associated with it (pointers), your resources get released multiple times. The destructors of local variables still in scope are called when the function ends, which could explain a crash.
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1