GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 19-Apr-2005, 07:13
Gamer_2k4's Avatar
Gamer_2k4 Gamer_2k4 is offline
Member
 
Join Date: Apr 2005
Location: Wisconsin
Posts: 117
Gamer_2k4 will become famous soon enough

Class Problem


I'm writing a rogue-like RPG in c++, and right now I'm having a problem with one of my classes. Here is my main file:
CPP / C++ / C Code:
#include "JZBlib.h" //include my header file

#include "forward.h"
#include "tiles.h"      //tiles.h supplies tile data for the game
#include "maps.h"      //maps.h supplies map data for the game
#include "monsters.h"   //monsters.h supplies monster data for the game
#include "env.h"

int main(int argc, char *argv[])
{   
    loadTiles();
    
    SetConsoleTitle("Adventures in Reptoran v0.0.1");
       
    //make the cursor invisible
    HANDLE hOut;
    CONSOLE_CURSOR_INFO ConCurInf;
    hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    ConCurInf.bVisible = FALSE;
    SetConsoleCursorInfo(hOut, &ConCurInf);
    
    Environment env;                                     //PROBLEM LINE
    Tile t[101][401];
    for (int i = 1; i <= 100; i++)
    {
        for (int j = 1; j <= 400; j++)
        {
            int r = Randint(1, 5);
            if (r > 2) r = 1;
            t[i][j] = allTiles[r];
        }
    }            
    //Map m(40, 160, t);
    //env.setMap(m);
    //env.addMonster(Monster(4, "@"));
    
    //env.addMonster(Monster(2, "h", 5, 5));
    //while (env.step() == 0) {}
    system("cls");
    return 1;
}

Most of the code here is irrelevant (I think), but the program generates a runtime error. When I comment out the line marked "PROBLEM LINE", the program runs ok. However, I kind of need the environment class for my entire game. Here is its code:
CPP / C++ / C Code:
class Environment
{
public:
       Environment(){}
       void updateDisplay(Monster m);
       int step(); //returns if the program should exit 0: keep going; 1: exit; 2: save, then exit;
       Monster* getMonster(int x, int y) {return map[x][y].monsterHere();}
       Tile* getTile(int x, int y);
       void setMap(Map m) {CurrentMap = m;}
       void addMonster(Monster m);
       Map getMap() {return CurrentMap;}
       //void getItems(int x, int y, vector<Item>* i);
private:
       Tile map[101][401];
       int monsters;
       Monster monstersHere[256];
       //vector<Item> itemsHere(0);
       Map CurrentMap;
};

Also, method declarations are included. The program compiles with no errors and no warnings. However, when I try to declare the Environment object, a pop-up error message is displayed and the program exits. The Map object also has the same problem. What's wrong with my code?
  #2  
Old 19-Apr-2005, 08:00
QED's Avatar
QED QED is offline
Member
 
Join Date: Feb 2005
Location: Hudson Valley, NY
Posts: 231
QED is a jewel in the roughQED is a jewel in the roughQED is a jewel in the rough
Could you post the code for your Map class? Since the crash occurs when you declare either Map or Environment, and since an Environment contains a Map, I suspect the problem is in Map.

Matthew
  #3  
Old 19-Apr-2005, 08:07
Gamer_2k4's Avatar
Gamer_2k4 Gamer_2k4 is offline
Member
 
Join Date: Apr 2005
Location: Wisconsin
Posts: 117
Gamer_2k4 will become famous soon enough
Ok, sure. Here it is:
CPP / C++ / C Code:
class Map
{
public:
      Map(){}
      Map(int h, int w, Tile t[101][401]);

      void setTile(int x, int y, Tile t) {tiles[x][y] = t;}
      
      Tile tiles[101][401];
      int height;
      int width;
      int xMin;
      int xMax;
      int yMin;
      int yMax;
};

Map::Map(int h, int w, Tile t[101][401])
{
       height = h;
       width = w;
       xMin = 0;
       yMin = 0;
       xMax = h - 20;
       yMax = w - 80;
       for (int i = 1; i <= 100; i++)
       {
           for(int j = 1; j <= 400; j++)
           {
               tiles[i][j] = t[i][j];
           }
       }
}

int totalMaps = 0;
vector<Map> allMaps(0);
  #4  
Old 19-Apr-2005, 12:49
QED's Avatar
QED QED is offline
Member
 
Join Date: Feb 2005
Location: Hudson Valley, NY
Posts: 231
QED is a jewel in the roughQED is a jewel in the roughQED is a jewel in the rough
Hmm... I am sorry to say that I do not see the source of the error in the code you have posted (maybe I'm missing it). BUT, what I do see is that you are passing complex objects to functions as by-value parameters, rather than by-reference.
CPP / C++ / C Code:
void setTile(int x, int y, Tile t) {tiles[x][y] = t;}
This is not a good idea for several reasons, but also may point us to a possible source of this error. A better alternative for C++ would be
CPP / C++ / C Code:
void setTile(int x, int y, Tile const& t) {tiles[x][y] = t;}
Each time you pass an object by-value, your program will actually make a temporary copy of that object, which has scope only for the duration of the function. Hence, the object goes out of scope when the function ends, and the destructor is called.

Another thing I noticed is that you have not defined copy constructors or assignment operators for your objects. This means that the compiler will generate default definitions for these functions, which may not do the right thing. For example, if your object contains a member variable that is a pointer to another object, then the default copy constructor (and assignment operator) will make only a shallow copy of the member; that is, a copy of the pointer address, not a new object instance that is like the original member variable.

What I am thinking at this point is that the error probably results from the program making a copy of a temporary object (by constructor or assignment), and then the temporary is destroyed and the copy contains a pointer to some out object that no longer exists. Then, somewhere the program tries to use that non-existent object, and CRASH! The classes Tile and/or Monster are likely suspects from the portions of code I can see here.

I may be way off here regarding the cause of the error, but I do recommend not using pass-by-value in C++ with complex objects. Unnecessary overhead for the copying, plus it may not be doing what you think it is if default copy constructor and assignment are used.

To try to solve this yourself, try placing some printf(), or cout, statements throughout the code to help pinpoint where exactly this error is occurring. I understand that this can be very tedious if you have a lot of code and no idea where to start. I do have an idea about that, however.

That's about all I can come up with unless you can post some debug output or additonal code.

Matthew

P.S. I also noticed that your classes do not have destructors declared. It is very possible that for your some of your classes the default destructor is not appropriate.
  #5  
Old 21-Apr-2005, 20:28
FlipNode FlipNode is offline
New Member
 
Join Date: Mar 2005
Posts: 14
FlipNode is on a distinguished road

maybe this is the problem


Environment(){}

i usually do it this way

Environment();

i could be wrong.. )
  #6  
Old 22-Apr-2005, 07:03
Gamer_2k4's Avatar
Gamer_2k4 Gamer_2k4 is offline
Member
 
Join Date: Apr 2005
Location: Wisconsin
Posts: 117
Gamer_2k4 will become famous soon enough

Pointer Problem


Ok, I'm replacing object refrences in the class with object pointers. However, I'm adding them the the Environment class like this:
CPP / C++ / C Code:
env.addMonster(Monster(4, "@"));
So I'm not exactly sure what is being pointed to (Environment contains an array of Monster pointers called monstersHere). Does the Monster object go out of scope after the method is called, or does it remain initialized until the program exits?
  #7  
Old 22-Apr-2005, 07:06
Gamer_2k4's Avatar
Gamer_2k4 Gamer_2k4 is offline
Member
 
Join Date: Apr 2005
Location: Wisconsin
Posts: 117
Gamer_2k4 will become famous soon enough
Quote:
Originally Posted by FlipNode
Environment(){}

i usually do it this way

Environment();

Is this in the class declaration or when you're creating an Environment object? My compile (Dev-c++) throws an error when I try to create an object that way...
  #8  
Old 22-Apr-2005, 08:20
QED's Avatar
QED QED is offline
Member
 
Join Date: Feb 2005
Location: Hudson Valley, NY
Posts: 231
QED is a jewel in the roughQED is a jewel in the roughQED is a jewel in the rough
Quote:
Originally Posted by Gamer_2k4
... I'm adding them the the Environment class like this: ...
So I'm not exactly sure what is being pointed to (Environment contains an array of Monster pointers called monstersHere). Does the Monster object go out of scope after the method is called, or does it remain initialized until the program exits?
In your example, the following code
CPP / C++ / C Code:
env.addMonster(Monster(4, "@"));
means that a temporary instance of Monster is created to be passed to the method addMonster(). This temporary object does indeed go out-of-scope when the function returns. If addMonster() is placing the address of this temporary object in the array, then afterwards that address points to nothing; rather, it does not point to what you think it does, very likely not a Monster.

If you are managing these Monsters using pointers inside your classes, then the method addMonster() should take a pointer or non-const-reference to a Monster instead of a Monster by-value. Then, your method call might look like this,
CPP / C++ / C Code:
env.addMonster(new Monster(4, "@"));
The new operator in C++ returns a pointer, in this case to a newly created (on the heap) Monster object. This Monster does not go out-of-scope or get destroyed upon return of addMonster().

I am intending here to provide some insight related to your question, and not to suggest that might code example be used as it is. At this point, I don't have enough understanding of your specific program to make such a suggestion.


I'll be happy to try answering further questions.

Matthew
  #9  
Old 22-Apr-2005, 08:23
QED's Avatar
QED QED is offline
Member
 
Join Date: Feb 2005
Location: Hudson Valley, NY
Posts: 231
QED is a jewel in the roughQED is a jewel in the roughQED is a jewel in the rough
Quote:
Originally Posted by FlipNode
i usually do it this way

Environment();

i could be wrong.. )

Either usage is correct. Note that that with your version the constructor still needs to be defined somewhere. Probably, outside the class declaration, in an implementation .cpp rather than the header file.

Though it is often preferred to define methods, including constructors, outside the class declaration, it is still correct to both declare and define in one shot.

Matthew
 
 

Recent GIDBlogMeeting the populace by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Inheritance problem CaptnB C++ Forum 2 27-Jan-2005 08:09
Error C2146: syntax error : missing ',' before identifier 'C4' mattchew008 C++ Forum 2 19-Dec-2004 06:06
hashing help saiz66 C++ Forum 1 06-Jul-2004 06:16
problem with creating class mohammed C++ Forum 1 11-Oct-2003 09:04

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 17:33.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.