forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

"this" pointer changed?

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
Criptych



Joined: 12 Sep 2009
Posts: 79

PostPosted: Thu Sep 17, 2009 2:43 am    Post subject: "this" pointer changed? Reply with quote

This is really more a general programming question, but it's a PSP application, so I thought I'd ask here. For starters, I have the following class:
Code:

class Viewpoint
{
public:
   Viewpoint(int source) { Viewpoint(source, 0, 0, 0); }
   Viewpoint(int source, float zoom, float lon, float lat);

   void Scroll(float x, float y);
   void Zoom(float step);
   void Project(int &tx, int &ty, int &tz, int &ts, int &px, int &py);

   int source; float zoom, scale, lon, lat;
};


Now, in my main function, I create a Viewpoint, and call Project on it each frame. Since it was giving me strange results (usually crashes!), I added some debug messages, and got this in my output:
Code:

Viewpoint.cpp:45: Viewpoint::Viewpoint(0x9fbfd88): zoom == 0.000000, scale == 1.000000, lon == 0.000000, lat == -0.000046
Viewpoint.cpp:87: Viewpoint::Project(0x9fbfddc): zoom == 0.000000, scale == 0.000000

The values in parentheses are the "this" pointer at each call. What I don't understand is why, when I only created one Viewpoint in the entire program, "this" has a different value in Project than it did in the constructor? I've tried creating it on the stack and on the heap, but it happens in both cases, and I've never seen it before.
Back to top
View user's profile Send private message
jbit
Site Admin


Joined: 28 May 2005
Posts: 293
Location: København, Danmark

PostPosted: Thu Sep 17, 2009 3:11 am    Post subject: Reply with quote

Without more code it's impossible to tell.... However it could be memory corruption (over running a buffer?) or pointer screw up.. but since the pointers are quite close together my guess is you're doing something like...
Code:
Viewpoint *view = new Viewpoint();
view++;
view->Project();
Back to top
View user's profile Send private message Visit poster's website
Criptych



Joined: 12 Sep 2009
Posts: 79

PostPosted: Thu Sep 17, 2009 3:29 am    Post subject: Reply with quote

But I don't have any pointer manipulations. The section where it's used looks like this (parts removed for brevity):
Code:

   Viewpoint view(0);

   while (running)
   {
      // update animations, etc.

      if (pressed(PSP_CTRL_LEFT))  view.Scroll(-1, 0);
      if (pressed(PSP_CTRL_RIGHT)) view.Scroll(+1, 0);
      if (pressed(PSP_CTRL_UP))    view.Scroll(0, -1);
      if (pressed(PSP_CTRL_DOWN))  view.Scroll(0, +1);
      if (pressed(PSP_CTRL_LTRIGGER)) view.Zoom(-1);
      if (pressed(PSP_CTRL_RTRIGGER)) view.Zoom(+1);

      int tx, ty, tz, ts, px, py;
      view.Project(tx, ty, tz, ts, px, py);

      startDrawing();

      for (int j = -1; j <= 1; j++)
      {
         for (int i = -1; i <= 1; i++)
         {
            getTile(view.source, tz, tx + i, ty + j)->Draw(px + i*ts, py + j*ts, ts, ts);
         }
      }

      // show coordinate info

      endDrawing();
      swapBuffers();
   }


The code worked fine with a struct, but it was a little messy, so I was trying to get some encapsulation going. I don't want to go back if I can help it, though.
Back to top
View user's profile Send private message
psPea



Joined: 01 Sep 2007
Posts: 64

PostPosted: Thu Sep 17, 2009 4:23 am    Post subject: Reply with quote

I think
Code:
   Viewpoint(int source) { Viewpoint(source, 0, 0, 0); }
   Viewpoint(int source, float zoom, float lon, float lat);
looks very messy, you should use
Code:
   Viewpoint(int source, float zoom = 0, float lon = 0, float lat = 0);
instead
_________________
Click ME!
Back to top
View user's profile Send private message Yahoo Messenger MSN Messenger
Criptych



Joined: 12 Sep 2009
Posts: 79

PostPosted: Thu Sep 17, 2009 6:01 am    Post subject: Reply with quote

Well, it's been a while since I've used C++ to this extent, I guess I'm used to the C# way of doing it. :)

EDIT: Added more debug messages, and now it seems that the constructor is the only place where "this" points somewhere different. All other calls have the same address as the "real" address of the object.
Could I have just been (un)lucky enough to stumble on an obscure compiler bug? As I said, I have never seen this happen before; I have half a dozen other classes in my project, and none of them has exhibited the same problem.

I also found a little workaround that is helping, but I'm still curious about why this happened.
Back to top
View user's profile Send private message
psPea



Joined: 01 Sep 2007
Posts: 64

PostPosted: Thu Sep 17, 2009 9:59 am    Post subject: Reply with quote

Maybe this is only initialized after the constructor returns.
_________________
Click ME!
Back to top
View user's profile Send private message Yahoo Messenger MSN Messenger
Criptych



Joined: 12 Sep 2009
Posts: 79

PostPosted: Thu Sep 17, 2009 10:44 am    Post subject: Reply with quote

psPea wrote:
Maybe this is only initialized after the constructor returns.

I think it's supposed to be an idiom/placeholder rather than an actual variable to be "initialized." So it should point to "this" object no matter when it's used. Right?
Back to top
View user's profile Send private message
jbit
Site Admin


Joined: 28 May 2005
Posts: 293
Location: København, Danmark

PostPosted: Thu Sep 17, 2009 5:35 pm    Post subject: Reply with quote

Ugh, didn't notice you were doing odd things..... calling a constructor C# style does not do what you think it does!
Code:
class Test
{
        int m_iVar;
public:
        Test(int var)
        {
                printf("fake: %p\n", this);
                m_iVar = var;
        }
        Test()
        {
                m_iVar = 0;
                printf("mine: %p\n", this);
                Test(1);
        }
        void foo()
        {
                printf("using: %p (%d)\n", this, m_iVar);
        }
};
int main()
{
        Test t;
        t.foo();
}
prints
Code:
mine: 0xbffff8cc
fake: 0xbffff89c
using: 0xbffff8cc (0)

The constructor call inside the constructor makes a new object on the stack, calls the constructor on that, and then deletes it....

edit: Also, I can't see this working in C# either, as far as I know the only way to do this in C# would be constructor chaining which is:
Code:
class Test
{
    int m_iVar;
public:
   Test(int var) { m_iVar = var; }
   Test() : this(1)  {}
};

But as said above, the preferred (and simplest) way for this specific use case is to use default arguments ( Test(int var = 1) ).
Back to top
View user's profile Send private message Visit poster's website
Criptych



Joined: 12 Sep 2009
Posts: 79

PostPosted: Thu Sep 17, 2009 11:18 pm    Post subject: Reply with quote

jbit wrote:
The constructor call inside the constructor makes a new object on the stack, calls the constructor on that, and then deletes it....

>.< That explains it, then.

jbit wrote:
edit: Also, I can't see this working in C# either, as far as I know the only way to do this in C# would be constructor chaining

That's what I was trying to do, but I couldn't remember the C++ syntax (and was too busy/lazy/distracted at the time to JFGI). Since what I wrote compiled, I thought I'd gotten it.

EDIT: And now having done so, I learn that there is no syntax for it. Bah. :P

Thanks for your help. :)
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group