Author Topic: More problems with pointers :(  (Read 7805 times)

0 Members and 1 Guest are viewing this topic.

Offline mike_g

  • Amiga 1200
  • ****
  • Posts: 435
  • Karma: 34
    • View Profile
More problems with pointers :(
« on: May 11, 2007 »
I'm still having problems with pointers. This time I want to return a pointer to an object from a member function, but i cant seem to get it to work.

Heres the class definition:
Code: [Select]
class rooms
{
    private:
        int number;
        float cost;
        guests *p; // <------------------ My pointer
    public:
        rooms();
        ~rooms();
        int GetNumber();
        float GetCost();
        guests GetGuest(); // <---------- Get pointer function
        void AddGuest();
        void SetNumber(int);
        void SetCost(float);
}; 
Heres my get pointer function:
Code: [Select]
guests rooms::GetGuest()            {return *p;}And heres where I call it:
Code: [Select]
         if(room[i].GetGuest() != NULL)
            cout << "Booked\n";
        else
            cout << "Vacant\n";
This wont compile, but if I change the if statement to this:
Code: [Select]
if(&room[i].GetGuest() != NULL)It will but the prog crashes. Apart from that I have experimented with loads of different possibilites, but nothing wants to compile :( Can someone tell me what I am doing wrong here ??? Thanks.



Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: More problems with pointers :(
« Reply #1 on: May 11, 2007 »
Somewhere you need to allocate space for guests.
Code: [Select]
class rooms
{
    private:
        int number;
        float cost;
        guests *p; // <------------------ My pointer
    public:
        rooms();
        ~rooms();
        int GetNumber();
        float GetCost();
        guests *GetGuest(); // return a pointer to the guest data
        void AddGuest();
        void SetNumber(int);
        void SetCost(float);
};  Heres my get pointer function:


guests *rooms::GetGuest()            {return p;} // return the pointer

         if(room[i].GetGuest() != NULL)
            cout << "Booked\n";
        else
            cout << "Vacant\n";
That will work, but you still need to create some space for that guest
Code: [Select]
void rooms::AddGuest( ... information about guest ...)
{
  p = new guests; //allocate some room for the guest info
 p->blah = information about guest
}
and you need to be able to free that memory
Code: [Select]
void rooms::RemoveGuest()
{
  if (p)
  {
    delete p;
    p = NULL;
  }
}
You might want to call RemoveGuest() in the destructor (~rooms())
How does that look?

Jim
Challenge Trophies Won:

Offline mike_g

  • Amiga 1200
  • ****
  • Posts: 435
  • Karma: 34
    • View Profile
Re: More problems with pointers :(
« Reply #2 on: May 11, 2007 »
Thanks Jim. It doesnt quite solve my problem tho. My fault really I spose because I dident post all the relevant code.

At the start of the main function I run the constructor for each room setting the guest pointer to NULL. I then want to check if the rooms to see if they are vacant of not by getting the pointer value. Heres the code in full hopefully its more helpful:
Code: [Select]
#include <iostream>
#include <string.h>
using namespace std;

#define num_rooms 10

class guests; //Forward Declaration Of the class Guests

class rooms
{
    private:
        int number;
        float cost;
        guests *p;
    public:
        rooms();
        ~rooms();
        int GetNumber();
        float GetCost();
    //Added setter  functions 
        guests GetGuest();
        void AddGuest();
        void SetNumber(int);
        void SetCost(float);
};     

class guests //: rooms //guests are derived from rooms WHY? dumb requirement
{
    private:
        char surname[10];
        int bill; 
    public:
        guests();
        ~guests();
        void EndGuest();
        char* GetName();
        void AddCharge(int);
        float GetBill();         
};     

void InitRooms(rooms*);
char MainMenu();
void CheckAvail(rooms*);
void CheckIn(rooms*);

void Cls();


int main()
{
    short select;
   
    rooms room[num_rooms];         //Constuct 10 rooms as globals
    InitRooms(&room[1]);           //Set the variables for each room   
   
    //MAIN LOOP;
    while(select != '5')
    {
        Cls();
        select = MainMenu();
       
        if(select == '1')
            CheckAvail(&room[1]);
        else if(select == '2')
            CheckIn(&room[1]);
        else if(select == '3')
            Cls();
        else if(select == '4')
            Cls();
        //Cls();
        //cout << select;
    }

}   

//---- GUEST MEMBER FUNCTIONS ------------------------------//
guests::guests()                                            //
{                                                           //
     cout << "enter name: ";                                //
     cin >> surname;                                        //
     bill=0;                                                //
}                                                           //
guests::~guests()                                           //
{                                                           //
     cout << "Guest is leaving final bill to pay: $";       //
}                                                           //
char* guests::GetName()             { return surname; }     //
void  guests::AddCharge(int charge) { bill=bill+charge; }   //
float guests::GetBill()             { return bill; }        //
//---- ROOM MEMBER FUNCTIONS -------------------------------//               
rooms::rooms()                                              //
{                                                           //
    number=0;                                               //
    cost=0;                                                 //
    p=NULL;                                                 //
}                                                           //
                                                            //
rooms::~rooms(){}                                           //
int   rooms::GetNumber()            { return number; }      //
float rooms::GetCost()              { return cost;  }       //
void  rooms::SetNumber(int n)       { number = n; }         //
void  rooms::SetCost(float c)       { cost = c; }           //
void  rooms::AddGuest()             
{
    p = new guests; //Set the pointer to the location of the new guest created
    guests(); //Run constructor for new guest 
}
guests rooms::GetGuest()            {return *p;}
//----- INITIALIZE ROOMS -----------------------------------//
void InitRooms(rooms *room)
{
    for(int i=1; i<=10; i++) room[i].SetNumber(i);
   
    room[1].SetCost(100);  room[2].SetCost(90);                     
    room[3].SetCost(85.5); room[4].SetCost(80); 
    room[5].SetCost(80);   room[6].SetCost(50); 
    room[7].SetCost(50);   room[8].SetCost(45.5); 
    room[9].SetCost(45.5); room[10].SetCost(40); 
}   
//----- MAIN MENU DISPLAY ----------------------------------//
char MainMenu()
{
    char temp[100];
    cout << "<*>---===MAIN MENU===---<*>\n\n";
    cout << "1: Check available rooms and prices\n";
    cout << "2: Book a guest into a room\n";
    cout << "3: Add a charge to a guests bill\n";
    cout << "4: Guest checkout\n";
    cout << "5: Exit \n\n";
    cout << "Enter selection: ";
    gets(temp); //Get input as a string
    //Validate the first character and ensure input is one character
    while(temp[0] < 49 || temp[0] > 53 || strlen(temp) != 1)
    {
        cout << "Invalid selection please re enter: ";
        gets(temp);
    }
    return temp[0];
}   
//------- DISPLAY DETAILS ABOUT ROOMS -------------------------//
void CheckAvail(rooms *room)
{
    char temp[100];
    Cls();
   
    for(int i=1; i<=num_rooms; i++)
    {
        cout << "Room: " << room[i].GetNumber() << " \tat $" << room[i].GetCost() << "\t";         
        // p = room[i].GetGuest();
        if(room[i].GetGuest() != NULL)
            cout << "Booked\n";
        else
            cout << "Vacant\n";
    }
   
    cout << "\nPress Enter to return to the main menu.";
    for(int i=1; i<=13;i++) cout << "\n";
    gets(temp);       
}     

void CheckIn(rooms *room)
{
    short no;
    cout << "Check guest into room number: ";
    cin >> no;
    room[no].AddGuest();
}     

void Cls() {for(int i=1;i<=25;i++)cout << "\n";} 
If I can get this pointer returned from the function somehow, the rest should be straightforward, cheers.




Offline mike_g

  • Amiga 1200
  • ****
  • Posts: 435
  • Karma: 34
    • View Profile
Re: More problems with pointers :(
« Reply #3 on: May 11, 2007 »
Sorry for the double post. I see what you are saying jim about allocating room for the guests. The thing is that they are only meant to be created when they check into a room, then destroyed as they leave. If a guest does not exist, I don't think it should cause problems with checking the pointer in the rooms class that points to Null. But maybe I am wrong ???

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: More problems with pointers :(
« Reply #4 on: May 11, 2007 »
Your first problem is in C++ arrays count from 0, so all the stuff where you have
Code: [Select]
rooms room[10];
for (i = 1; i <= 10; i++)
is going to be reading/writing outside the array causing all sorts of problems.
Code: [Select]
room rooms[10];
for (i = 0; i < 10; i++)

I'm still looking in to whether there's another problem.

Jim

Jim
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: More problems with pointers :(
« Reply #5 on: May 11, 2007 »
Code: [Select]
void  rooms::AddGuest()             
{
    p = new guests; //Set the pointer to the location of the new guest created
    guests(); //Run constructor for new guest 
}
You're definitely confused here.  When you call 'new' the constructor for the object you're creating (a guest) is called automatically.

Quote
the pointer in the rooms class that points to Null
It's not "points to NULL" it's "the pointer is NULL".  That's a much better way of thinking about it.  A NULL pointer doesn't point to anything.

Jim
Challenge Trophies Won:

Offline mike_g

  • Amiga 1200
  • ****
  • Posts: 435
  • Karma: 34
    • View Profile
Re: More problems with pointers :(
« Reply #6 on: May 11, 2007 »
For the arrays the number of rooms is 10. I thought that that would create 11 entries in the array from 0 to 10. Thats what it does in Blitz, but it may not be the same for C. For the guest constuctor, yep, I was definitely confused there  ;D  :-[

With the pointer, if it dosent point to anything would that make this test invalid somehow:
Code: [Select]
if(room[i].GetGuest() != NULL)

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: More problems with pointers :(
« Reply #7 on: May 11, 2007 »
In C and C++, when you ask for 10 entries, you get 10 entries, not 11!  It's different from Blitz and you need to fix it.

Code: [Select]
if(room[i].GetGuest() != NULL)That's the right test though.  As long as the room has had its constructor called, then GetGuest will return NULL if there's no guest there.

When you delete the room you must check to see if there was a guest in there and free it if it's present.  So just
Code: [Select]
if (p) delete p;
in the destructor for the room

Jim
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: More problems with pointers :(
« Reply #8 on: May 12, 2007 »
If you fix the array indexing so it goes 0-9
Code: [Select]
for (i=0;i<num_rooms;i++)

and change

Code: [Select]
guests rooms::GetGuest()            {return *p;}
to
Code: [Select]
guests *rooms::GetGuest()            {return p;}

You're 99% of the way there.  There's just a couple of tiny errors after that.

Jim
Challenge Trophies Won:

Offline mike_g

  • Amiga 1200
  • ****
  • Posts: 435
  • Karma: 34
    • View Profile
Re: More problems with pointers :(
« Reply #9 on: May 12, 2007 »
Thanks for spending some time going through my code and help out. Have some k :)

I tried this:
Code: [Select]
guests *rooms::GetGuest()            {return p;}But it wouldnt work for me :(

I think it has something to do with the pointer being dereferenced when it is passed from the function. I have just read something dereferencing here

Quote
The dereference operation starts at the pointer and follows its arrow over to access its pointee. The goal may be to look at the pointee state or to change the pointee state.

The dereference operation on a pointer only works if the pointer has a pointee -- the pointee must be allocated and the pointer must be set to point to it. The most common error in pointer code is forgetting to set up the pointee. The most common runtime crash because of that error in the code is a failed dereference operation. In Java the incorrect dereference will be flagged politely by the runtime system. In compiled languages such as C, C++, and Pascal, the incorrect dereference will sometimes crash, and other times corrupt memory in some subtle, random way. Pointer bugs in compiled languages can be difficult to track down for this reason.

If NULL means that the pointer points to nothing, then it seems as if my code will not work at all, but the prog should at least compile, then crash.

The only way I have been able to get it to compile is by doing:
Code: [Select]
guests rooms::GetGuest()            { return *p; }then:
Code: [Select]
if(&room[i].GetGuest() != NULL)and it crashes at the if statement.   

Maybe I could set the pointers to point some variable thats memory address represents that there is no guest in the room. I don't know if that would be a bad idea tho.

Also, from what I experience, It dosent seem as if what you said about the array sizes was correct. I remembered coding a bubble sort in C using array entry 0 as a temp variable. I just wrote a short test example:
Code: [Select]
#include <stdio.h>
int array[10];
int main()
{
    for(int i=0; i<=10; i++) array[i]=i, printf("%i", array[i]);   
    getchar(), getchar();
}
I use Dev-C++ and it works for me. Maybe different compilers interpret C differently or something.





Offline mike_g

  • Amiga 1200
  • ****
  • Posts: 435
  • Karma: 34
    • View Profile
Re: More problems with pointers :(
« Reply #10 on: May 12, 2007 »
>_< it works i just for forgot to do this guests *GetGuest(); at the declaration. Thanks dude :)

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: More problems with pointers :(
« Reply #11 on: May 12, 2007 »
Excellent!!

Checking whether a pointer is NULL isn't dereferencing, the dereference comes when you try to read the data pointed to by the pointer.

One small problem you still have is that 'select' isn't set to anything when you first enter the while loop in main.  You probably also need to fix the displayed room numbers to start from 1 now the array starts from 0.

Quote
Also, from what I experience, It dosent seem as if what you said about the array sizes was correct. I remembered coding a bubble sort in C using array entry 0 as a temp variable. I just wrote a short test example:

Code: :updance:
#include <stdio.h>
int array[10];
int main()
{
    for(int i=0; i<=10; i++) array=i, printf("%i", array);   
    getchar(), getchar();
} I use Dev-C++ and it works for me. Maybe different compilers interpret C differently or something.
No.  I'm definitely correct, you're just lucky it doesn't crash.  There is a strict standard that all C compilers must comply to, otherwise they're not C compilers.  All C compilers are supposed to produce the same results with correct code.  If your code is incorrect, they can do anything they like, in this case it produces a working program from wrong source code.

Jim
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: More problems with pointers :(
« Reply #12 on: May 12, 2007 »
Try this little sample to see if DevC++ is the same as my compiler
Code: [Select]
#include <stdio.h>
typedef struct
{
int myarray[5];
int anotherint;
} thing;

int main(void)
{
thing mything;
int x;

mything.anotherint = 10;
printf("%d\n", mything.anotherint);
for (x = 0; x <= 5; x++)
mything.myarray[x] = 1;
printf("%d\n", mything.anotherint);
getchar();
return 0;
}
On my box it prints
10
1
How did that happen?  I bet yours is the same :D
If you change the 5 in the for loop to a 4 you should get
10
10

Jim
Challenge Trophies Won:

Offline mike_g

  • Amiga 1200
  • ****
  • Posts: 435
  • Karma: 34
    • View Profile
Re: More problems with pointers :(
« Reply #13 on: May 12, 2007 »
Quote
On my box it prints
10
1
How did that happen?  I bet yours is the same Cheesy
If you change the 5 in the for loop to a 4 you should get
10
10
Yep, same results here. Guess I'm going to have to start at 0 in the future.  I'm a little bit sad that I wasent right about anything :'(  But still this stuff is all good to know :D

As for the room numbers, theyre all fixed now. For some reason I declared select as a short, when its meant to be a char o_0, got it initiated now as well. So yeah its all go go go from here on.
« Last Edit: May 12, 2007 by mike_g »

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: More problems with pointers :(
« Reply #14 on: May 12, 2007 »
I think it's excellent that you're learning C++.  The pointers stuff is hard to start with, but incredibly powerful once you understand how it's all supposed to work.

Is this for an assignment or something you're trying out for yourself?

Jim
Challenge Trophies Won:

Offline mike_g

  • Amiga 1200
  • ****
  • Posts: 435
  • Karma: 34
    • View Profile
Re: More problems with pointers :(
« Reply #15 on: May 12, 2007 »
This is for an assignment, but I want to learn C/C++ better as its fast and widely used. I don't have much time to code for fun at the moment, I got 5 assignments to finish over the next couple of weeks, including big ass reports.

Still I got SDL set up so when this busy period is over I want to have a go at doing some stuff with graphics using it. Console apps are a bit boring really.