Qbasicnews.com

Full Version: what's wrong here? (ooplike)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
as soon you start uncomment the me.cubed or me.timesX it crashes...

Code:
'
' An OOP-like demo.
' thanks to David of xblite
'

TYPE OOPLIKE
  var AS LONG
  squared AS FUNCTION (this as OOPLIKE) as integer
  cubed   AS FUNCTION (this as OOPLIKE) as integer
  timesX  AS FUNCTION (this as OOPLIKE, byval x as integer) as integer
END TYPE

DECLARE FUNCTION Initialize (byval b as integer) as OOPLIKE ptr
DECLARE FUNCTION Squared (this as OOPLIKE ) as integer
DECLARE FUNCTION Cubed (this as OOPLIKE) as integer
DECLARE FUNCTION TimesX (this as OOPLIKE, byval x as integer) as integer

' start
    dim SHARED as OOPLIKE me, you

    me  = *Initialize (3)
    you = *Initialize (5)

    PRINT "================="

    PRINT "me.var      " ; me.var
    PRINT "me.squared  " ; me.squared (me)
'    PRINT "me.cubed    " ; me.cubed   (me)
'    PRINT "me.timesX   " ; me.timesX  (me, 100)

    PRINT "================="

    PRINT "you.var     " ; you.var
    PRINT "you.squared " ; you.squared (you)
'    PRINT "you.cubed   " ; you.cubed   (you)
'    PRINT "you.timesX  " ; you.timesX  (you, 100)

    PRINT "================="

    PRINT "Changing .var in me and you"

    me.var  = 6
    you.var = 7


    PRINT "================="

    PRINT "me.var      " ; me.var
    PRINT "me.squared  " ; me.squared (me)
'    PRINT "me.cubed    " ; me.cubed   (me)
'    PRINT "me.timesX   " ; me.timesX  (me, 100)

    PRINT "================="

    PRINT "you.var     " ; you.var
    PRINT "you.squared " ; you.squared (you)
'    PRINT "you.cubed   " ; you.cubed   (you)
'    PRINT "you.timesX  " ; you.timesX  (you, 100)

    PRINT "================="

        INPUT "press ENTER to exit..." ,pause




END
'
'
' ###########################
' #####  Initialize ()  #####
' ###########################
'
FUNCTION  Initialize (byval b as integer) as OOPLIKE ptr

  dim this as OOPLIKE

  this.var     = b
  this.squared = @Squared ()
  this.cubed   = @Cubed ()
  this.timesX  = @TimesX ()

  RETURN @this

END FUNCTION
'
'
' ########################
' #####  Squared ()  #####
' ########################
'
FUNCTION  Squared (this as OOPLIKE) as integer

  RETURN this.var * this.var

END FUNCTION
'
'
' ######################
' #####  Cubed ()  #####
' ######################
'
FUNCTION  Cubed (this as OOPLIKE) as integer

  RETURN this.var * this.var * this.var

END FUNCTION
'
'
' #######################
' #####  TimesX ()  #####
' #######################
'
FUNCTION  TimesX (this as OOPLIKE, byval x as integer) as integer

  RETURN this.var * x

END FUNCTION
just found out that if the structure is changed to
Code:
TYPE OOPLIKE
  var AS LONG
  squared AS FUNCTION (this as OOPLIKE) as integer
  cubed   AS FUNCTION (this as OOPLIKE) as integer
  timesX  AS FUNCTION (this as OOPLIKE, byval x as integer) as integer
  addspace     AS LONG  'add this for cubed function
  addmorespace AS LONG  'add this for timesX function
END TYPE
it works.

WHY?

@vic: if this is a compiler bug could you please provide a new fbc & rtl libs? (chicken/egg problem...)
Code:
FUNCTION  Initialize (byval b as integer) as OOPLIKE ptr

  dim this as OOPLIKE

  this.var     = b
  this.squared = @Squared ()
  this.cubed   = @Cubed ()
  this.timesX  = @TimesX ()

  RETURN @this

END FUNCTION
You return a pointer to a structure that no longe exists (it is deallocated when the function returns, as it is a local variable).

A solution could be to allocate it as dynamic memory:
Code:
function Initialize (byval b as integer) as OOPLike ptr
  
   dim this as OOPLike ptr
  
   this = callocate(len(OOPLike))
   this->var     = b
   this->squared = @Squared ()
   this->cubed   = @Cubed ()
   this->timesX  = @TimesX ()
  
   return this
  
end function
but then you must remember to deallocate the memory allocated later on.

Happy coding!
you could in addition to joakims suggestion write a small garbage collector that keeps track of the memory you allocated and deletes it either at program end, or during program execution time ( though this would need some thinking Smile ).

Zire has a simple "garbage collector" afair, go ask IT.
Thank you both for your reply.

Don't have time right now to try it out yet, but if it's a mem dealloc problem, than why does it work if I change the structure?

Can't wait to have more time and try it out.
Big Grin
Code:
this = callocate(len(OOPLIKE))
the compiler refuses to compile (invalid data type).


I did some more tests: as long there are the 2 additional variables in the structure, I can add more functions inside the structure (before the 2 additional variables).

Strange isn't it ...

... because if it's a matter of:
Quote:... return a pointer to a structure that no longe exists (it is deallocated when the function returns, as it is a local variable).

than it shouldn't work either way (with additional variables or not).


And this code works with no problems with xblite...

What am I missing?
As I see it, you have a pointer to deallocated memory. This is a great way to spawn hard-to-find bugs, as it'll work sometimes and other times not. I can't tell you why padding the structure makes it work (maybe v1ctor can), but it's NOT a solution to the problem. You should never return a pointer to a local variable.
I had this question awhile ago too. Vic just said do the dynamic allocation or just declare it as a Static variable.

Code:
Static this As OOPLIKE
Then the memory pointed to will change every time you call the function...
Thanks for the explanation.

I figured out why it works on xBlite:
xBlite is able to return structures, no pointer needed.

Vic, could we get structures as return argument?

BTW: Vic, don't hesitate to add your thoughts on this dilemma.
Pages: 1 2