I don't understand what is happening to my program...

I have a feeling that private members are marked private for a reason, because I'm having a serious error with accessing base-class data types via inheritance and declaring friends within classes...

If you run the test program after attaching the header in your include file you'll understand what I mean... the code is attached.

Sorry, I would actually post it but it's far too long and I have a feeling that the error may exist in more places since I used the friend modifier extensively =/

Note: I was trying to create a Game Creation library (well, namely for RPG's so I was going to rename it) by using a menu-type cluster object as well as "action" objects clustered together to be fired all at once, or select firing or both. Basically the purpose of the program is to allow flexibility for users to create their own games.

Edit: To be more clear, the information I'm trying to access isn't appearing on the screen properly or not at all.

Attachments
class Game_Object; //a component that can be added to the game
class _Manipulator; //a manipulator that has the right to manipulate other engine_parts
class Engine_Part; //a peice of the engine - performs independant functionality
class Engine; //simply a collection of Engine_Parts, but can be treated as a _Manipulator
class Creature; //abstract class that defines "living" creatures in the game
class PlayableCharacter; //for controllable characters
class NonPlayableCharacter; //for enemies and npcs
class Parameters; //holds information for a Game_Object
class Inventory; //Inventory for all living creatures in the game
class Item; //Items that are visible in the game
class Selector; //Works like an engine, but the objects stored are selected before, or during run-time

class Parameters{
       friend class PlayableCharacter;
       friend class NonPlayableCharacter;
       
       private:
               struct MAX_STATS{
                    public:
                               
                      int HP_M, MP_M, INCLOSE_M, EXP_TNL;
                      
                      MAX_STATS(){HP_M = 27, MP_M = 10, INCLOSE_M = 13, EXP_TNL = 250;};
                      MAX_STATS(int hp, int mp, int inclose, int exp){
                          HP_M = hp; MP_M = mp; INCLOSE_M = inclose; EXP_TNL = exp;          
                      }
                      
                      int &operator[] (int arg){
                          switch(arg){
                              case 0:
                                     return HP_M;
                              case 1:
                                     return MP_M;
                              case 2:
                                     return INCLOSE_M;
                              case 3:
                                     return EXP_TNL;
                              default:
                                      return HP_M;       
                          }
                      }
                      
                      char *operator[] (double arg){
                          int value = static_cast<int>(arg);
                          switch(value){
                              case 0:
                                     return "MAX HP";
                              case 1:
                                     return "MAX MP";
                              case 2:
                                     return "INCLOSE PEAK";
                              case 3:
                                     return "EXP to next LVL";
                              default:
                                      return "MAX HP";       
                          }
                      }                      
               } ms;
               
               struct CURRENT_STATS{
                  public:
                         
                      int HP, MP, INCLOSE, EXP;
                      
                      CURRENT_STATS(){HP = 27, MP = 10, INCLOSE = 0, EXP = 0;};
                      CURRENT_STATS(int hp, int mp, int inclose, int exp){
                          HP = hp; MP = mp; INCLOSE = inclose; EXP = exp;          
                      }                     
                      
                      int &operator[] (int arg){
                          switch(arg){
                              case 0:
                                     return HP;
                              case 1:
                                     return MP;
                              case 2:
                                     return INCLOSE;
                              case 3:
                                     return EXP;
                              default:
                                      return HP;       
                          }
                      }
                      
                      char *operator[] (double arg){
                          int value = static_cast<int>(arg);
                          switch(value){
                              case 0:
                                     return "HP";
                              case 1:
                                     return "MP";
                              case 2:
                                     return "INCLOSE";
                              case 3:
                                     return "EXP";
                              default:
                                      return "HP";       
                          }
                      }                      
               } cs;
               
               struct PRIMARY_STATS{
                  public:
                         
                      int LEVEL, STR, ACC, DODGE, INT, ARMOR, SPI_ARM;
                      
                      PRIMARY_STATS(){LEVEL = 1, STR = 5, ACC = 3, DODGE = 1, INT = 2, ARMOR = 10, SPI_ARM = 5;};
                      PRIMARY_STATS(int lvl, int str, int acc, int dod, int magi, int arm, int spi){
                            LEVEL = lvl; STR = str; ACC = acc; DODGE = dod; INT = magi; ARMOR = arm;
                            SPI_ARM = spi;         
                      }
                      
                      int &operator[] (int arg){
                          switch(arg){
                              case 0:
                                     return LEVEL;
                              case 1:
                                     return STR;
                              case 2:
                                     return ACC;
                              case 3:
                                     return DODGE;
                              case 4:
                                     return INT;
                              case 5:
                                     return ARMOR;
                              case 6:
                                     return SPI_ARM;
                              default:
                                      return LEVEL;       
                          }
                      }
                      
                      char *operator[] (double arg){
                          int value = static_cast<int>(arg);
                          switch(value){
                              case 0:
                                     return "LVL";
                              case 1:
                                     return "STR";
                              case 2:
                                     return "ACC";
                              case 3:
                                     return "DOD";
                              case 4:
                                     return "INT";
                              case 5:
                                     return "ARM";
                              case 6:
                                     return "SPI";
                              default:
                                      return "LVL";       
                          }
                      }                                            
               } ps;
               
       public:
              std::ostream &setParametersVisible(bool condition, int streamRowPosition, int streamColPosition){
                   //Code to manipulate how the parameters will appear on the screen...
                   return std::cout;           
              };
};

class Item{     
      friend class Inventory;
      friend class PlayableCharacter;
      
      private:
              char itemSymbol;
              
      protected:
             Item(char c){itemSymbol = c;};
      
      public:
             virtual char getSymbol(){return itemSymbol;};
             bool operator== (Item &other){return itemSymbol == other.getSymbol();};
             bool operator== (char arg){return getSymbol() == arg;};          
};

class Inventory{
       private:
               Item **items, *temporary;
               int currentRowSize, currentColSize;
       
       protected:
                 Inventory(int &size){
                     if(size <= 1)
                        size = 1;
                     else if(size > 20)
                        size = 20;
                     
                     items = (Item**)malloc(size * sizeof(Item*));          
                     currentRowSize = currentColSize = size;
                     temporary = 0;
                      
                     for(int i = 0; i < size; i++)
                        items[i] = (Item*)malloc(size * sizeof(Item));
                         
                     for(int i = 0; i < size; i++){
                        for(int j = 0; j < size; j++){
                             Item temp ('_');
                             items[i][j] = temp;
                        }
                     }                       
                 };
       
       public:
              Inventory(){
                   items = (Item**)malloc(5 * sizeof(Item*));
                   temporary = 0;
                   
                   currentRowSize = 5;
                   currentColSize = 5;
                   
                   for(int i = 0; i < 5; i++)
                        items[i] = (Item*)malloc(5 * sizeof(Item));
                         
                   for(int i = 0; i < 5; i++){
                        for(int j = 0; j < 5; j++){
                             Item temp ('_');
                             items[i][j] = temp;
                        }
                   }      
              };
              
              void increaseSize(){
                   if( currentRowSize <= 9 && currentColSize <= 9 ){
                       currentRowSize++;
                       currentColSize++;
                   }
                   else std::cout << "Bag size limit reached!" << std::endl;
              };
              
              Item &getItem(int row, int column){
                   Item *temp = 0;
                   
                   if(row >= 0 && row < currentRowSize
                   && column >= 0 && column < currentColSize)
#include <cstdlib>
#include <iostream>
#include "GameCreator.h"

using namespace std;

class A_Character : public PlayableCharacter
{
      public:
             A_Character(char *name) : PlayableCharacter(name)
             {
                    cout << "Creating Character: " << name << endl;     
             }
             
} bound ("Bound"), adephi ("Adephi");

class MyEnginePart : public Engine_Part
{
      public:
             MyEnginePart(char *name) 
             : Engine_Part(name)
             {
                  cout << "Creating Engine part: " << name << endl;
                  
                  addObject(bound);
                  addObject(adephi);            
             };
             
             void run()
             {
                  (*this)[0].printParameters();
                  (*this)[0].printParameters();
             }
} firstEPart ("first");


int main(int argc, char *argv[])
{
    Engine_Part *parts = &firstEPart;
    
    Selector sl ("Main selector", parts, 1);
    sl.run();
    
    cin.get();
    return 0;
}

After a quick look into it, I suggest that you get rid of malloc() usage. You are using 'delete' on memory that has been malloc'ed - that must not happen.
Then about 'delete', you only can delete something that has been allocated by 'new', consider

class a
{
public:
    a(){}

} instance; // an instance of class a

void somefunction(a* aptr)
{
    delete aptr;
}
int main()
{
    a * aptr = new a;

    somefunction(aptr);  // this is OK

    somefunction(&instance);    // <- must not happen

    return 0;
}

There were some other issues too, but I think first you could make sure that the basic memory operations are in order.
When I tried the program, addObject(adephi); causes the run-time to report damaged heap.

After a quick look into it, I suggest that you get rid of malloc() usage. You are using 'delete' on memory that has been malloc'ed - that must not happen.
Then about 'delete', you only can delete something that has been allocated by 'new', consider

class a
{
public:
    a(){}

} instance; // an instance of class a

void somefunction(a* aptr)
{
    delete aptr;
}
int main()
{
    a * aptr = new a;

    somefunction(aptr);  // this is OK

    somefunction(&instance);    // <- must not happen

    return 0;
}

There were some other issues too, but I think first you could make sure that the basic memory operations are in order.
When I tried the program, addObject(adephi); causes the run-time to report damaged heap.

Oh that's interesting. I was told to delete memory that was dynamically allocated and that malloc was one of the types that you could delete?

On a side note I'm using Dev-Cpp 4.9 and I haven't updated my compiler so I don't get those kind of warnings unfortunately.

Oh that's interesting. I was told to delete memory that was dynamically allocated and that malloc was one of the types that you could delete?

On a side note I'm using Dev-Cpp 4.9 and I haven't updated my compiler so I don't get those kind of warnings unfortunately.

Whenever you use malloc() then free the memory using free().
Whenever you use new, then free the memory using delete.

Whenever you use malloc() then free the memory using free().
Whenever you use new, then free the memory using delete.

Thank you very much for the clarification.

I made the changes. Here are the files with the revisions.

Attachments
class Game_Object; //a component that can be added to the game
class _Manipulator; //a manipulator that has the right to manipulate other engine_parts
class Engine_Part; //a peice of the engine - performs independant functionality
class Engine; //simply a collection of Engine_Parts, but can be treated as a _Manipulator
class Creature; //abstract class that defines "living" creatures in the game
class PlayableCharacter; //for controllable characters
class NonPlayableCharacter; //for enemies and npcs
class Parameters; //holds information for a Game_Object
class Inventory; //Inventory for all living creatures in the game
class Item; //Items that are visible in the game
class Selector; //Works like an engine, but the objects stored are selected before, or during run-time

class Parameters{
       friend class PlayableCharacter;
       friend class NonPlayableCharacter;
       
       private:
               struct MAX_STATS{
                    public:
                               
                      int HP_M, MP_M, INCLOSE_M, EXP_TNL;
                      
                      MAX_STATS(){HP_M = 27, MP_M = 10, INCLOSE_M = 13, EXP_TNL = 250;};
                      MAX_STATS(int hp, int mp, int inclose, int exp){
                          HP_M = hp; MP_M = mp; INCLOSE_M = inclose; EXP_TNL = exp;          
                      }
                      
                      int &operator[] (int arg){
                          switch(arg){
                              case 0:
                                     return HP_M;
                              case 1:
                                     return MP_M;
                              case 2:
                                     return INCLOSE_M;
                              case 3:
                                     return EXP_TNL;
                              default:
                                      return HP_M;       
                          }
                      }
                      
                      char *operator[] (double arg){
                          int value = static_cast<int>(arg);
                          switch(value){
                              case 0:
                                     return "MAX HP";
                              case 1:
                                     return "MAX MP";
                              case 2:
                                     return "INCLOSE PEAK";
                              case 3:
                                     return "EXP to next LVL";
                              default:
                                      return "MAX HP";       
                          }
                      }                      
               } ms;
               
               struct CURRENT_STATS{
                  public:
                         
                      int HP, MP, INCLOSE, EXP;
                      
                      CURRENT_STATS(){HP = 27, MP = 10, INCLOSE = 0, EXP = 0;};
                      CURRENT_STATS(int hp, int mp, int inclose, int exp){
                          HP = hp; MP = mp; INCLOSE = inclose; EXP = exp;          
                      }                     
                      
                      int &operator[] (int arg){
                          switch(arg){
                              case 0:
                                     return HP;
                              case 1:
                                     return MP;
                              case 2:
                                     return INCLOSE;
                              case 3:
                                     return EXP;
                              default:
                                      return HP;       
                          }
                      }
                      
                      char *operator[] (double arg){
                          int value = static_cast<int>(arg);
                          switch(value){
                              case 0:
                                     return "HP";
                              case 1:
                                     return "MP";
                              case 2:
                                     return "INCLOSE";
                              case 3:
                                     return "EXP";
                              default:
                                      return "HP";       
                          }
                      }                      
               } cs;
               
               struct PRIMARY_STATS{
                  public:
                         
                      int LEVEL, STR, ACC, DODGE, INT, ARMOR, SPI_ARM;
                      
                      PRIMARY_STATS(){LEVEL = 1, STR = 5, ACC = 3, DODGE = 1, INT = 2, ARMOR = 10, SPI_ARM = 5;};
                      PRIMARY_STATS(int lvl, int str, int acc, int dod, int magi, int arm, int spi){
                            LEVEL = lvl; STR = str; ACC = acc; DODGE = dod; INT = magi; ARMOR = arm;
                            SPI_ARM = spi;         
                      }
                      
                      int &operator[] (int arg){
                          switch(arg){
                              case 0:
                                     return LEVEL;
                              case 1:
                                     return STR;
                              case 2:
                                     return ACC;
                              case 3:
                                     return DODGE;
                              case 4:
                                     return INT;
                              case 5:
                                     return ARMOR;
                              case 6:
                                     return SPI_ARM;
                              default:
                                      return LEVEL;       
                          }
                      }
                      
                      char *operator[] (double arg){
                          int value = static_cast<int>(arg);
                          switch(value){
                              case 0:
                                     return "LVL";
                              case 1:
                                     return "STR";
                              case 2:
                                     return "ACC";
                              case 3:
                                     return "DOD";
                              case 4:
                                     return "INT";
                              case 5:
                                     return "ARM";
                              case 6:
                                     return "SPI";
                              default:
                                      return "LVL";       
                          }
                      }                                            
               } ps;
               
       public:
              std::ostream &setParametersVisible(bool condition, int streamRowPosition, int streamColPosition){
                   //Code to manipulate how the parameters will appear on the screen...
                   return std::cout;           
              };
};

class Item{     
      friend class Inventory;
      friend class PlayableCharacter;
      
      private:
              char itemSymbol;
              
      protected:
             Item(char c){itemSymbol = c;};
      
      public:
             virtual char getSymbol(){return itemSymbol;};
             bool operator== (Item &other){return itemSymbol == other.getSymbol();};
             bool operator== (char arg){return getSymbol() == arg;};          
};

class Inventory{
       private:
               Item **items, *temporary;
               int currentRowSize, currentColSize;
       
       protected:
                 Inventory(int &size){
                     if(size <= 1)
                        size = 1;
                     else if(size > 20)
                        size = 20;
                     
                     items = (Item**)malloc(size * sizeof(Item*));          
                     currentRowSize = currentColSize = size;
                     temporary = 0;
                      
                     for(int i = 0; i < size; i++)
                        items[i] = (Item*)malloc(size * sizeof(Item)); //use free and NOT delete when malloc
                         
                     for(int i = 0; i < size; i++){
                        for(int j = 0; j < size; j++){
                             Item temp ('_');
                             items[i][j] = temp;
                        }
                     }                       
                 };
       
       public:
              Inventory(){
                   items = (Item**)malloc(5 * sizeof(Item*));
                   temporary = 0;
                   
                   currentRowSize = 5;
                   currentColSize = 5;
                   
                   for(int i = 0; i < 5; i++)
                        items[i] = (Item*)malloc(5 * sizeof(Item)); //use free and NOT delete when malloc
                         
                   for(int i = 0; i < 5; i++){
                        for(int j = 0; j < 5; j++){
                             Item temp ('_');
                             items[i][j] = temp;
                        }
                   }      
              };
              
              ~Inventory()
              {
                     for(int i = 0; i < currentRowSize; i++)
                          free((void*)items[i]);
                          
                     free((void*)items);
              };
              
              void increaseSize(){
                   if( currentRowSize <= 9 && currentColSize <= 9 ){
                       currentRowSize++;
                       currentColSize++;
                   }
#include <cstdlib>
#include <iostream>
#include "GameCreator.h"

using namespace std;

class A_Character : public PlayableCharacter
{
      public:
             A_Character(char *name) : PlayableCharacter(name)
             {
                    cout << "Creating Character: " << name << endl;     
             }
             
} bound ("Bound"), adephi ("Adephi");

class MyEnginePart : public Engine_Part
{
      public:
             MyEnginePart(char *name) 
             : Engine_Part(name)
             {
                  cout << "Creating Engine part: " << name << endl;
                  
                  addObject(bound);
                  addObject(adephi);            
             };
             
             void run()
             {
                  (*this)[0].printParameters();
                  (*this)[0].printParameters();
             }
} firstEPart ("first");


int main(int argc, char *argv[])
{
    Engine_Part *parts = &firstEPart;
    
    Selector sl ("Main selector", parts, 1);
    sl.run();
    
    cin.get();
    return 0;
}

Thank you very much for the clarification.

I made the changes. Here are the files with the revisions.

Hmm, wouldn't it be better to drop usage of malloc()/free() since you are working with objects instead of raw native types i.e. consistently use new/delete. And maybe consider e.g. STL list for storing objects/object pointers, to save yourself the hassle of memory management.

Anyway, note that you must not issue free() on anything that has not been malloc'ed. That is just what is now happening in addObject(), that crashes the program at very early stages (before main() is called).

Hmm, wouldn't it be better to drop usage of malloc()/free() since you are working with objects instead of raw native types i.e. consistently use new/delete. And maybe consider e.g. STL list for storing objects/object pointers, to save yourself the hassle of memory management.

Anyway, note that you must not issue free() on anything that has not been malloc'ed. That is just what is now happening in addObject(), that crashes the program at very early stages (before main() is called).

Ah I see what's happening.

Because I didn't use new on my objects, their constructors never ran therefore the data was never initialized in the first place!

Wow I learned an incredible lesson here.

The reason why I used malloc instead of new was because I was looking for an alternative around allocating memory for temporary/abstract objects since they require an extension and override within the extensions.

Apparently I was trying to cheat the system and I get bit in the ass for doing so =/

I'll make the changes again. Thank you very much.

Honestly, my compiler is not giving me these warnings! What compiler should I update to in order to get these messages?

Honestly, my compiler is not giving me these warnings! What compiler should I update to in order to get these messages?

Those are not compiler warnings but instead run-time checks wrt heap usage. The compiler will not catch the errors that occur in the program, but the run-time checks will alert you on the spot. Try e.g. a VC ++ Express 2008.

It appears that you are not yet fully understanding about memory allocation/deallocation, so
if you use the malloc/free, every pointer you 'free' must have been malloc'ed, no exceptions.
if you use the new/delete, every pointer you 'delete' must have been new'ed, no exceptions.

I'm also trying to say that if you have a non-dynamic 'object', you must not issue free nor delete on a pointer to such object. This in mind, go through the code and see what happens with e.g. [B]bound[/B] ("Bound"), [B]adephi[/B] ("Adephi"); .

Those are not compiler warnings but instead run-time checks wrt heap usage. The compiler will not catch the errors that occur in the program, but the run-time checks will alert you on the spot. Try e.g. a VC ++ Express 2008.

It appears that you are not yet fully understanding about memory allocation/deallocation, so
if you use the malloc/free, every pointer you 'free' must have been malloc'ed, no exceptions.
if you use the new/delete, every pointer you 'delete' must have been new'ed, no exceptions.

I'm also trying to say that if you have a non-dynamic 'object', you must not issue free nor delete on a pointer to such object. This in mind, go through the code and see what happens with e.g. [B]bound[/B] ("Bound"), [B]adephi[/B] ("Adephi"); .

I think I understand a bit more now. I've revised the code again and this time I also dynamically allocated memory for char pointers I declared in class-scope.

Here are the revisions again, and this time it seems as if the program is working... but if there are still errors please point them out.

Edit: Oh actually there is one issue - I'm having trouble comparing a null-initialized char-array to a char pointer. What would you suggest?

Attachments
class Game_Object; //a component that can be added to the game
class _Manipulator; //a manipulator that has the right to manipulate other engine_parts
class Engine_Part; //a peice of the engine - performs independant functionality
class Engine; //simply a collection of Engine_Parts, but can be treated as a _Manipulator
class Creature; //abstract class that defines "living" creatures in the game
class PlayableCharacter; //for controllable characters
class NonPlayableCharacter; //for enemies and npcs
class Parameters; //holds information for a Game_Object
class Inventory; //Inventory for all living creatures in the game
class Item; //Items that are visible in the game
class Selector; //Works like an engine, but the objects stored are selected before, or during run-time

/**
LESSON! DO NOT USE MALLOC ON NON-PRIMITIVE TYPES!!! USE MALLOC ONLY FOR PRIMITIVES!

MALLOC MEANS THAT THE OBJECTS CONSTRUCTOR WONT BE RUN AND THAT SPACE WILL
BE ALLOCATED FOR THE OBJECT! NEW ENSURES THE CONSTRUCTOR WILL RUN AND DELETE ENSURES DESTRUCTOR WILL RUN!
*/
class Parameters{
       friend class PlayableCharacter;
       friend class NonPlayableCharacter;
       
       private:
               struct MAX_STATS{
                    public:
                               
                      int HP_M, MP_M, INCLOSE_M, EXP_TNL;
                      
                      MAX_STATS(){HP_M = 27, MP_M = 10, INCLOSE_M = 13, EXP_TNL = 250;};
                      MAX_STATS(int hp, int mp, int inclose, int exp){
                          HP_M = hp; MP_M = mp; INCLOSE_M = inclose; EXP_TNL = exp;          
                      }
                      
                      int &operator[] (int arg){
                          switch(arg){
                              case 0:
                                     return HP_M;
                              case 1:
                                     return MP_M;
                              case 2:
                                     return INCLOSE_M;
                              case 3:
                                     return EXP_TNL;
                              default:
                                      return HP_M;       
                          }
                      }
                      
                      char *operator[] (double arg){
                          int value = static_cast<int>(arg);
                          switch(value){
                              case 0:
                                     return "MAX HP";
                              case 1:
                                     return "MAX MP";
                              case 2:
                                     return "INCLOSE PEAK";
                              case 3:
                                     return "EXP to next LVL";
                              default:
                                      return "MAX HP";       
                          }
                      }                      
               } ms;
               
               struct CURRENT_STATS{
                  public:
                         
                      int HP, MP, INCLOSE, EXP;
                      
                      CURRENT_STATS(){HP = 27, MP = 10, INCLOSE = 0, EXP = 0;};
                      CURRENT_STATS(int hp, int mp, int inclose, int exp){
                          HP = hp; MP = mp; INCLOSE = inclose; EXP = exp;          
                      }                     
                      
                      int &operator[] (int arg){
                          switch(arg){
                              case 0:
                                     return HP;
                              case 1:
                                     return MP;
                              case 2:
                                     return INCLOSE;
                              case 3:
                                     return EXP;
                              default:
                                      return HP;       
                          }
                      }
                      
                      char *operator[] (double arg){
                          int value = static_cast<int>(arg);
                          switch(value){
                              case 0:
                                     return "HP";
                              case 1:
                                     return "MP";
                              case 2:
                                     return "INCLOSE";
                              case 3:
                                     return "EXP";
                              default:
                                      return "HP";       
                          }
                      }                      
               } cs;
               
               struct PRIMARY_STATS{
                  public:
                         
                      int LEVEL, STR, ACC, DODGE, INT, ARMOR, SPI_ARM;
                      
                      PRIMARY_STATS(){LEVEL = 1, STR = 5, ACC = 3, DODGE = 1, INT = 2, ARMOR = 10, SPI_ARM = 5;};
                      PRIMARY_STATS(int lvl, int str, int acc, int dod, int magi, int arm, int spi){
                            LEVEL = lvl; STR = str; ACC = acc; DODGE = dod; INT = magi; ARMOR = arm;
                            SPI_ARM = spi;         
                      }
                      
                      int &operator[] (int arg){
                          switch(arg){
                              case 0:
                                     return LEVEL;
                              case 1:
                                     return STR;
                              case 2:
                                     return ACC;
                              case 3:
                                     return DODGE;
                              case 4:
                                     return INT;
                              case 5:
                                     return ARMOR;
                              case 6:
                                     return SPI_ARM;
                              default:
                                      return LEVEL;       
                          }
                      }
                      
                      char *operator[] (double arg){
                          int value = static_cast<int>(arg);
                          switch(value){
                              case 0:
                                     return "LVL";
                              case 1:
                                     return "STR";
                              case 2:
                                     return "ACC";
                              case 3:
                                     return "DOD";
                              case 4:
                                     return "INT";
                              case 5:
                                     return "ARM";
                              case 6:
                                     return "SPI";
                              default:
                                      return "LVL";       
                          }
                      }                                            
               } ps;
               
       public:
              std::ostream &setParametersVisible(bool condition, int streamRowPosition, int streamColPosition){
                   //Code to manipulate how the parameters will appear on the screen...
                   return std::cout;           
              };
};

class Item{     
      friend class Inventory;
      friend class PlayableCharacter;
      
      private:
              char itemSymbol;
              Item(){itemSymbol = '_';};
              
      protected:
             Item(char c){itemSymbol = c;};
      
      public:
             virtual char getSymbol(){return itemSymbol;};
             bool operator== (Item &other){return itemSymbol == other.getSymbol();};
             bool operator== (char arg){return getSymbol() == arg;};          
};

class Inventory{
       private:
               Item **items, *temporary;
               int currentRowSize, currentColSize;
       
       protected:
                 Inventory(int &size){
                     if(size <= 1)
                        size = 1;
                     else if(size > 20)
                        size = 20;
                              
                     currentRowSize = currentColSize = size;
                     temporary = 0;
                      
                     items = new Item*[size]; 
                      
                     for(int i = 0; i < size; i++)
                        items[i] = new Item[size]; //use new for classes, and malloc for primitive types                    
                 };
       
       public:
              Inventory(){
                   items = new Item*[5];
                   temporary = 0;
                   
                   currentRowSize = 5;
                   currentColSize = 5;
                   
                   for(int i = 0; i < 5; i++){
                        items[i] = new Item[5];                     //use free and NOT delete when malloc
                      }                                             //Also since these are objects, use                                                 
              };                                                    //new/delete instead of malloc/free
              
              ~Inventory()
              {
                     for(int i = 0; i < currentRowSize; i++)
                          delete items[i];
                          
                     delete items;
              };
              
              void increaseSize(){
                   if( currentRowSize <= 9 && currentColSize <= 9 ){
                       currentRowSize++;
                       currentColSize++;
                   }
                   else std::cout << "Bag size limi
#include <cstdlib>
#include <iostream>
#include "GameCreator.h"

using namespace std;

class A_Character : public PlayableCharacter{
      public:
             A_Character(char *name) : PlayableCharacter(name){
                    cout << "Creating Character: " << name << endl;     
             }
             
             A_Character(): PlayableCharacter("NameNotSet"){cout << "Creating Character: " << "NOTSET" << endl;};
             
             void setName(char *arg){objName = arg;};
};

class MyEnginePart : public Engine_Part{
      public:
             MyEnginePart(char *name, A_Character *player1, A_Character *player2) 
             : Engine_Part(name){
                  cout << "Creating Engine part: " << name << endl;
                  
                  addObject(*player1);
                  addObject(*player2);            
             };
             
             void run(){
                  (*this)[0].printParameters();
                  (*this)[1].printParameters();
             }
};


int main(int argc, char *argv[]){
    A_Character *player1 = new A_Character ("Bound");
    A_Character *player2 = new A_Character ("Adephi");
    
    MyEnginePart *mep = new MyEnginePart ("First", player1, player2);
    
    Selector *sl = new Selector("Main Menu", mep, 1);
    
    sl->run();
    
 //   player1->printParameters();
    
    cin.get();
    return 0;
}

Nevermind about the comparison, I created a class that does char pointer to char pointer comparisons.

My biggest problem now is the process of running the engine part's run overridden run method.

I have the revised files listed with the addition of the class I created to do the comparison.

Edit: Did some more revisions... found the error.

I was attempting to "free" memory from the previously allocated indice in the addObject portion of the code but I simply deleted the pointer gluing the other pointers together causing them to float freely, then allocated them to a temporary pointer then reallocated them to the regular double pointer... Hopefully I did this process correctly.

At the moment no information is lost and the virtual run method is overridden by the user's Engine Part run method which is exactly what I wanted. If there's still a problem with this please let me know.

Game_Object **tempPtr = new Game_Object*[amount];
                              
                           for(int i = 0; i < amount; i++){
                              tempPtr[i] = new Game_Object[1];     
                              tempPtr[i] = obj[i];
                           }
                           delete[] obj; //deletes the pointer pointing to the pointers, causing the pointers
                                         //to "float" freely in memory, but tempPtr holds a ref to them
                           
                           obj = new Game_Object*[amount];
                          
                           for(int i = 0; i < amount; i++){
                              obj[i] = new Game_Object[1];
                              obj[i] = tempPtr[i];
                              
                           } 
                          delete tempPtr;
Attachments
#pragma once
#include "string_lib.h"


class Game_Object; //a component that can be added to the game
class _Manipulator; //a manipulator that has the right to manipulate other engine_parts
class Engine_Part; //a peice of the engine - performs independant functionality
class Engine; //simply a collection of Engine_Parts, but can be treated as a _Manipulator
class Creature; //abstract class that defines "living" creatures in the game
class PlayableCharacter; //for controllable characters
class NonPlayableCharacter; //for enemies and npcs
class Parameters; //holds information for a Game_Object
class Inventory; //Inventory for all living creatures in the game
class Item; //Items that are visible in the game
class Selector; //Works like an engine, but the objects stored are selected before, or during run-time

/**
LESSON! DO NOT USE MALLOC ON NON-PRIMITIVE TYPES!!! USE MALLOC ONLY FOR PRIMITIVES!

MALLOC MEANS THAT THE OBJECTS CONSTRUCTOR WONT BE RUN AND THAT SPACE WILL
BE ALLOCATED FOR THE OBJECT! NEW ENSURES THE CONSTRUCTOR WILL RUN AND DELETE ENSURES DESTRUCTOR WILL RUN!
*/
class Parameters{
       friend class PlayableCharacter;
       friend class NonPlayableCharacter;
       
       private:
               struct MAX_STATS{
                    public:
                               
                      int HP_M, MP_M, INCLOSE_M, EXP_TNL;
                      
                      MAX_STATS(){HP_M = 27, MP_M = 10, INCLOSE_M = 13, EXP_TNL = 250;};
                      MAX_STATS(int hp, int mp, int inclose, int exp){
                          HP_M = hp; MP_M = mp; INCLOSE_M = inclose; EXP_TNL = exp;          
                      }
                      
                      int &operator[] (int arg){
                          switch(arg){
                              case 0:
                                     return HP_M;
                              case 1:
                                     return MP_M;
                              case 2:
                                     return INCLOSE_M;
                              case 3:
                                     return EXP_TNL;
                              default:
                                      return HP_M;       
                          }
                      }
                      
                      char *operator[] (double arg){
                          int value = static_cast<int>(arg);
                          switch(value){
                              case 0:
                                     return "MAX HP";
                              case 1:
                                     return "MAX MP";
                              case 2:
                                     return "INCLOSE PEAK";
                              case 3:
                                     return "EXP to next LVL";
                              default:
                                      return "MAX HP";       
                          }
                      }                      
               } ms;
               
               struct CURRENT_STATS{
                  public:
                         
                      int HP, MP, INCLOSE, EXP;
                      
                      CURRENT_STATS(){HP = 27, MP = 10, INCLOSE = 0, EXP = 0;};
                      CURRENT_STATS(int hp, int mp, int inclose, int exp){
                          HP = hp; MP = mp; INCLOSE = inclose; EXP = exp;          
                      }                     
                      
                      int &operator[] (int arg){
                          switch(arg){
                              case 0:
                                     return HP;
                              case 1:
                                     return MP;
                              case 2:
                                     return INCLOSE;
                              case 3:
                                     return EXP;
                              default:
                                      return HP;       
                          }
                      }
                      
                      char *operator[] (double arg){
                          int value = static_cast<int>(arg);
                          switch(value){
                              case 0:
                                     return "HP";
                              case 1:
                                     return "MP";
                              case 2:
                                     return "INCLOSE";
                              case 3:
                                     return "EXP";
                              default:
                                      return "HP";       
                          }
                      }                      
               } cs;
               
               struct PRIMARY_STATS{
                  public:
                         
                      int LEVEL, STR, ACC, DODGE, INT, ARMOR, SPI_ARM;
                      
                      PRIMARY_STATS(){LEVEL = 1, STR = 5, ACC = 3, DODGE = 1, INT = 2, ARMOR = 10, SPI_ARM = 5;};
                      PRIMARY_STATS(int lvl, int str, int acc, int dod, int magi, int arm, int spi){
                            LEVEL = lvl; STR = str; ACC = acc; DODGE = dod; INT = magi; ARMOR = arm;
                            SPI_ARM = spi;         
                      }
                      
                      int &operator[] (int arg){
                          switch(arg){
                              case 0:
                                     return LEVEL;
                              case 1:
                                     return STR;
                              case 2:
                                     return ACC;
                              case 3:
                                     return DODGE;
                              case 4:
                                     return INT;
                              case 5:
                                     return ARMOR;
                              case 6:
                                     return SPI_ARM;
                              default:
                                      return LEVEL;       
                          }
                      }
                      
                      char *operator[] (double arg){
                          int value = static_cast<int>(arg);
                          switch(value){
                              case 0:
                                     return "LVL";
                              case 1:
                                     return "STR";
                              case 2:
                                     return "ACC";
                              case 3:
                                     return "DOD";
                              case 4:
                                     return "INT";
                              case 5:
                                     return "ARM";
                              case 6:
                                     return "SPI";
                              default:
                                      return "LVL";       
                          }
                      }                                            
               } ps;
               
       public:
              std::ostream &setParametersVisible(bool condition, int streamRowPosition, int streamColPosition){
                   //Code to manipulate how the parameters will appear on the screen...
                   return std::cout;           
              };
};

class Item{     
      friend class Inventory;
      friend class PlayableCharacter;
      
      private:
              char itemSymbol;
              Item(){itemSymbol = '_';};
              
      protected:
             Item(char c){itemSymbol = c;};
      
      public:
             virtual char getSymbol(){return itemSymbol;};
             bool operator== (Item &other){return itemSymbol == other.getSymbol();};
             bool operator== (char arg){return getSymbol() == arg;};          
};

class Inventory{
       private:
               Item **items, *temporary;
               int currentRowSize, currentColSize;
       
       protected:
                 Inventory(int &size){
                     if(size <= 1)
                        size = 1;
                     else if(size > 20)
                        size = 20;
                              
                     currentRowSize = currentColSize = size;
                     temporary = 0;
                      
                     items = new Item*[size]; 
                      
                     for(int i = 0; i < size; i++)
                        items[i] = new Item[size]; //use new for classes, and malloc for primitive types                    
                 };
       
       public:
              Inventory(){
                   items = new Item*[5];
                   temporary = 0;
                   
                   currentRowSize = 5;
                   currentColSize = 5;
                   
                   for(int i = 0; i < 5; i++){
                        items[i] = new Item[5];                     //use free and NOT delete when malloc
                      }                                             //Also since these are objects, use                                                 
              };                                                    //new/delete instead of malloc/free
              
              ~Inventory()
              {
                     for(int i = 0; i < currentRowSize; i++)
                          delete items[i];
                          
                     delete items;
              };
              
              void increaseSize(){
                   if( currentRowSize <= 9 && currentColSize <= 9 ){
                       currentRowSize++;
                       currentColSize++;
                   }
#include <cstdlib>
#include <iostream>
#include "GameCreator.h"
#include "string_lib.h"

using namespace std;

class A_Character : public PlayableCharacter{
      public:
             A_Character(char *name) : PlayableCharacter(name){
                    cout << "Creating Character: " << name << endl;     
             }
             
             A_Character(): PlayableCharacter("NameNotSet"){cout << "Creating Character: " << "NOTSET" << endl;};
             
             void setName(char *arg){objName = arg;};
};

class MyEnginePart : public Engine_Part{
      public:
             MyEnginePart(char *name, A_Character *player1, A_Character *player2) 
             : Engine_Part(name){
                  cout << "Creating Engine part: " << name << endl;
                  
                  addObject(*player1);
                  addObject(*player2);            
             };
             
             void run(){
                  (*this)[0].printParameters();
                  (*this)[1].printParameters();
             }
};


int main(int argc, char *argv[]){
    
    
    A_Character *player1 = new A_Character ("Bound");
    A_Character *player2 = new A_Character ("Adephi");
    
    MyEnginePart *mep = new MyEnginePart ("First", player1, player2);
    
    Selector *sl = new Selector("Main Menu", mep, 1);
    
    sl->run();
    
    cin.get();
    cin.get();
    return 0;
}
#pragma once

class String_Manip
{
  
  public:
        
         bool compare(char* arg1, char* arg2)
         {
              int length1 = 0, length2 = 0, compCount = 0;
              
              for(int i = 0; arg1[i] != '\0'; i++)
                      length1++;
                      
              for(int i = 0; arg2[i] != '\0'; i++)
                      length2++;
                      
              if(length1 != length2)
                         return false;
              else
              {
                  for(int i = 0; i < length1; i++)
                  {
                          if(arg1[i] == arg2[i])
                              compCount++;
                  }
                  
                  return compCount == length1;
              }
         };
      
} s_manip;

Nevermind about the comparison, I created a class that does char pointer to char pointer comparisons.

// what will 'cmp' be ...
const int cmp = s_manip.compare("abc","abcd");

A diagnostics suggestion, add the following destructor

~Game_Object()
{
    std::cout << "~Game_Object(): " << objName << std::endl;
}

It will tell you that the memory management is not right.

You already have a Game_Object * in obj, you don't have to allocate and assign a new Game_Object ..

obj[i] = new Game_Object[1]; // you don't need this line
obj[i] = tempPtr[i];

Then strlen() returns the length of a string excluding the terminating NULL character but strcpy copies the string and appends the terminating NULL character <-> you have many one-byte-off memory allocations/assignments/overwrites there.

Then an example of a practice you effectively use

struct test
{
    int member_var;
    
    test() : member_var(0){}
    ~test(){}

    void f()
    {
        cout << member_var << endl;
    }

    static test & getObj()
    {
        test * p = 0;
        return *p;
    }
};

int main(int argc, char *argv[])
{
	test & obj = test::getObj();
	obj.f();

	return 0;
}

I wonder why are you not using std::string?

I still suggest to drop the manual allocation/reallocation schemes and use a STL container.

// what will 'cmp' be ...
const int cmp = s_manip.compare("abc","abcd");

I've tested that... it turned out to be false. I don't understand the point you were trying to make here.

A diagnostics suggestion, add the following destructor

~Game_Object()
{
    std::cout << "~Game_Object(): " << objName << std::endl;
}

It will tell you that the memory management is not right.

At first I was trying to make copies of the objects and reassign them in the addObject command, but then I decided to simply delete already allocated memory then allocate more memory for new objects and assign the old objects (along with the new one) back to the pointer.

You already have a Game_Object * in obj, you don't have to allocate and assign a new Game_Object ..

obj[i] = new Game_Object[1]; // you don't need this line
obj[i] = tempPtr[i];

Made the change, thank you. As you can see I am still not quite understanding pointer to pointers.

Then strlen() returns the length of a string excluding the terminating NULL character but strcpy copies the string and appends the terminating NULL character <-> you have many one-byte-off memory allocations/assignments/overwrites there.

I did try using strcmp but apparently there were problems comparing a string literal with a char array that had extensive null terminators.

Then an example of a practice you effectively use

struct test
{
    int member_var;
    
    test() : member_var(0){}
    ~test(){}

    void f()
    {
        cout << member_var << endl;
    }

    static test & getObj()
    {
        test * p = 0;
        return *p;
    }
};

int main(int argc, char *argv[])
{
	test & obj = test::getObj();
	obj.f();

	return 0;
}

I think you're asking why I'm returning a reference to NULL in some cases. It's for cases when the user attempts to access memory outside the bounds I defined. Either way they would get NULL returned if they accessed something outside of the boundaries, or will the reference return as void?

I'm not sure what else you could be implying here. It looks like you're returning a reference to a NULL object then using it as if it exists. I don't know where I've done that in my code, honestly. You'd have to give me some line numbers to examine because I don't see at all.

EDIT: I do however see a reason to this reply because I realized that if for some reason someone accessed an object in an Engine_Part and decided to set the reference to NULL then eventually I'd be accessing a NULL reference. I could provide a type of trim method that will resize and reallocate the pointer(s) to prevent this though.

I wonder why are you not using std::string?

I still suggest to drop the manual allocation/reallocation schemes and use a STL container.

Now that I know more about the differences between using strcpy and strlen I will use the std::string class more.

Also the main reason I attempted this project wasn't really to create a workable engine. It was just practice. I wanted to stay away from some of the STL's until I had a better understanding of memory management as well as the C language in general.

// what will 'cmp' be ...
const int cmp = s_manip.compare("abc","abcd");

// what will 'cmp' be ... const int cmp = s_manip.compare("abc","abcd");

I've tested that... it turned out to be false. I don't understand the point you were trying to make here.

My bad ... sorry about that one ...

// what will 'cmp' be ...
const int cmp = s_manip.compare("abc","abcd");

// what will 'cmp' be ... const int cmp = s_manip.compare("abc","abcd");

My bad ... sorry about that one ...

Honestly I'm more thankful than anything.

If I simply stuck to the book I've been reading currently and not coming to these forums my coding would've been incredibly bad, or at least unlearned.

You haven't given me any bad advice so far, so I don't take something "wrong" as an offense whatsoever.

This question has already been answered. Start a new discussion instead.