Extended variable destruction

General FreeBASIC programming questions.
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Extended variable destruction

Postby rolliebollocks » Apr 09, 2016 17:00

Why would a destructor that otherwise functions properly segfault on an object destruction called from an extended variable?
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Re: Extended variable destruction

Postby rolliebollocks » Apr 09, 2016 17:26

The code appears to call the destructor and for some reason there appears to be extra empty variables. When I call this from an extended object, it segfaults. I dunno what's going on.

Code: Select all

#include once "Parsing.bas"

#ifndef NULL
#define NULL 0
#endif

#DEFINE ___DEBUG

#DEFINE DBLQUOTE ascii(34)

enum varType
  _MALFORMED_ = 0
  _NUMBER_    = 1
  _STRING_    = 2
  _BOOL_      = 3
  _ARRAY_     = 4
  _OBJECT_    = 5
  _NULL_      = 6
end enum

enum JSON_BOOL
    _FALSE_ = 0
    _TRUE_  = 1
end enum

type variable_ as variable

type varArray
   
    Public:
        declare Destructor()
        declare sub add( byval item as variable_ ptr )
        declare function get( byval index as integer ) as variable_ ptr
        declare function getLength() as integer
        declare sub push( byval idx as integer, byval item as variable_ ptr )
        declare sub push( byval idx as integer, byref item as variable_ )
        declare sub pop( byval item as integer )
        declare sub push_back( byval item as variable_ ptr )
        declare sub clear()
           
        as integer size
        as variable_ ptr items(any)
       
end type

type varObjectField
    Public:
        declare Destructor()
        as string           key
        as variable_ ptr    value
end type

type varObject

    Public:
   
        declare Destructor()
        declare sub add( byval key as string, byval item as variable_ ptr )
        declare function get( byval key as string ) as variable_ ptr
        declare function getKey( byval index as integer ) as string
        declare function getValue( byval index as integer ) as variable_ ptr
        declare function getSize() as integer
        declare sub pop( byval idx as integer )
           
        as integer              size
        as varObjectField ptr   fields(any)

end type

type variable extends Object

    Public:
        declare Constructor()
        declare Constructor( byref rhs as variable )
        declare Constructor( byval json as string, byval n as string = "" )
        declare Constructor( byval n as double )
        declare Destructor()
        declare Operator Let( byref rhs as variable )
        declare Operator Let( byval json as string )
        declare Operator Let( byval n as double )
       
        declare sub         init( byval s as string, byval n as string = "" )
       
        declare function    getType() as string
        declare function    getTypeNum() as vartype
        declare function    toString() as string
     
        declare function    getNumber() as double
        declare function    getString() as string
        declare function    getBoolean() as integer
        declare function    getArray() as vararray ptr
        declare function    getObject() as varobject ptr

        as string           lbl
        as varType          typ
        as double           number
        as string           strng
        as integer          bool
        as varArray ptr     array
        as varObject ptr    object

end type

Destructor varArray()
#IFDEF ___DEBUG
    ? "Array destructor"
#ENDIF
    for i as integer = 0 to this.size-1
        delete items(i)
    next
    erase items
End Destructor

sub varArray.add( byval item as variable_ ptr )
    size += 1
    redim preserve items(size-1)
    items(size-1) = new variable_
    *items(size-1) = *item
end sub

sub varArray.push( byval idx as integer, byval item as variable_ ptr )
    if idx < 0 then exit sub
    if idx > size-1 then exit sub
   
    redim preserve items( size )
    items( size ) = new variable_
   
    for i as integer = size-1 to idx step -1
        swap items(i), items(i+1)
    next i
   
    *items( idx ) = *item
   
    size += 1
end sub

sub varArray.push( byval idx as integer, byref item as variable_ )
    if idx < 0 then exit sub
    if idx > size-1 then exit sub
   
    redim preserve items( size )
   
    for i as integer = size-1 to idx step -1
        swap items(i), items(i+1)
    next i
   
    *items( idx ) = item
   
    size += 1
end sub

sub varArray.push_back( byval item as variable_ ptr )   
    redim preserve items( size )
    items( size ) = new variable
    *items( size ) = *item
    size += 1
end sub

sub varArray.pop( byval idx as integer )
    if idx < 0 then exit sub
    if idx > size-1 then exit sub
    if size = 1 then
        erase( items )
        size = 0
        exit sub
    endif
   
    for i as integer = idx+1 to size-1
        items(i-1) = items(i)
    next
   
    size -= 1
    redim preserve items( 0 to size-1 )       
end sub

sub varArray.clear()
    for i as integer = 0 to size-1
        delete items(i)
    next i
    erase items
    size = 0
end sub

function varArray.get( byval index as integer ) as variable_ ptr
    if index >= size or index < 0 then return NULL
    return items(index)
end function

function varArray.getLength() as integer
    return size
end function

Destructor varObjectField()
#IFDEF ___DEBUG
    ? "Object field destructor"
#ENDIF
    if value then delete value
end Destructor

Destructor varObject
#IFDEF ___DEBUG
    ? "Object destructor"
#ENDIF   
    for i as integer = 0 to this.size-1
        if fields(i) then delete fields(i)
    next i
    erase fields
end Destructor

sub varObject.add( byval key as string, byval item as variable_ ptr )
    size += 1
    redim preserve fields(size-1)
    fields(size-1) = new varObjectField
    fields(size-1)->key = key
    fields(size-1)->value = new variable_
    *fields(size-1)->value = *item
end sub

function varObject.get( byval key as string ) as variable_ ptr
    key = chr(34)+key+chr(34)
    for i as integer = 0 to size-1
        if fields(i)->key = key then return fields(i)->value
    next i
    return 0
end function

function varObject.getKey( byval index as integer ) as string
    return fields(index)->key
end function

function varObject.getValue( byval index as integer ) as variable_ ptr
    return fields(index)->value
end function

function varObject.getSize() as integer
    return size
end function

sub varObject.pop( byval idx as integer )
    if idx < 0 then exit sub
    if idx > size-1 then exit sub
    if size = 1 then
        erase( fields )
        size = 0
        exit sub
    endif
   
    for i as integer = idx+1 to size-1
        fields(i-1) = fields(i)
    next
   
    size -= 1
    redim preserve fields( 0 to size-1 ) 
end sub

declare Operator = ( byref lhs as variable, byref rhs as variable ) as integer

Constructor variable()
end Constructor

Constructor variable( byref rhs as variable )
    this.lbl = rhs.lbl
    this.typ = rhs.typ
   
    select case rhs.typ
        case varType._BOOL_
            this.bool = rhs.bool
        case varType._NUMBER_
            this.number = rhs.number
        case varType._STRING_
            this.strng = rhs.strng
        case varType._OBJECT_
            this.object = new varObject
            redim this.object->fields( rhs.object->size - 1 )
            this.object->size = rhs.object->size
            if rhs.object->size then
                for i as integer = 0 to rhs.object->size - 1
                    this.object->fields(i) = new varObjectField
                    this.object->fields(i)->key = rhs.object->fields(i)->key
                    this.object->fields(i)->value = new variable
                    *this.object->fields(i)->value = *rhs.object->fields(i)->value
                next i
            end if
        case varType._ARRAY_
            this.array = new varArray
            if rhs.array->size then
                redim this.array->items( rhs.array->size - 1 )
                this.array->size = rhs.array->size
                for i as integer = 0 to rhs.array->size - 1
                    this.array->items(i) = new variable
                    *this.array->items(i) = *rhs.array->items(i)
                next i
            end if
    end select
End Constructor

Operator variable.Let( byref rhs as variable )
    if @this <> @rhs then
        this.lbl = rhs.lbl
        this.typ = rhs.typ
       
        select case rhs.typ
            case varType._BOOL_
                this.bool = rhs.bool
            case varType._NUMBER_
                this.number = rhs.number
            case varType._STRING_
                this.strng = rhs.strng
            case varType._OBJECT_
                this.object = new varObject
                redim this.object->fields( rhs.object->size - 1 )
                this.object->size = rhs.object->size
                if rhs.object->size then
                    for i as integer = 0 to rhs.object->size - 1
                        this.object->fields(i) = new varObjectField
                        this.object->fields(i)->key = rhs.object->fields(i)->key
                        this.object->fields(i)->value = new variable
                        *this.object->fields(i)->value = *rhs.object->fields(i)->value
                    next i
                end if
            case varType._ARRAY_
                this.array = new varArray
                if rhs.array->size then
                    this.array->size = rhs.array->size
                    redim this.array->items( rhs.array->size - 1 )
                    for i as integer = 0 to rhs.array->size - 1
                        this.array->items(i) = new variable
                        *this.array->items(i) = *rhs.array->items(i)
                    next i
                end if
             case else
            '? "Something is #%$@"
        end select
    end if
end Operator

sub copy_variable( byref var1 as variable, byref var2 as variable )
    var1.lbl = var2.lbl
    var1.typ = var2.typ
   
    select case var2.typ
        case _BOOL_
            var1.bool = var2.bool
        case _NUMBER_
            var1.number = var2.number
        case _STRING_
            var1.strng = var2.strng
        case _OBJECT_
            var1.object = new varObject
            redim var1.object->fields( var2.object->size - 1 )
            for i as integer = 0 to var2.object->size - 1
                var1.object->fields(i) = new varObjectField
                var1.object->fields(i)->key = var2.object->fields(i)->key
                *var1.object->fields(i)->value = *var2.object->fields(i)->value
            next i
        case _ARRAY_
            var1.array = new varArray
            redim var1.array->items( var2.array->size - 1 )
            var1.array->size = var2.array->size
           
            for i as integer = 0 to var2.array->size - 1
                var1.array->items(i) = new variable
                *var1.array->items(i) = *var2.array->items(i)
            next i
    end select
end sub

Constructor variable( byval json as string, byval n as string = "" )
    init( json, n )
end Constructor

Constructor variable( byval num as double )
    this.typ = _NUMBER_
    this.number = num
end Constructor

Operator variable.Let( byval json as string )
   init( json )
end Operator

Operator variable.Let( byval num as double )
    this.typ = _NUMBER_
    this.number = num
end Operator

Operator = ( byref lhs as varObjectField, byref rhs as varObjectField ) as integer
    if lhs.key <> rhs.key then return 0
    if ( *lhs.value = *rhs.value ) = 0 then return 0
    return -1
end Operator

Operator = ( byref lhs as variable, byref rhs as variable ) as integer
    if lhs.typ <> rhs.typ then return 0
    select case lhs.typ
    case varType._NUMBER_
        if lhs.number <> rhs.number then return 0
    case varType._STRING_
        if lhs.strng <> rhs.strng then return 0
    case varType._BOOL_
        if lhs.bool <> rhs.bool then return 0
    case varType._ARRAY_
        if lhs.array->size <> rhs.array->size then return 0
        for i as integer = 0 to lhs.array->size-1
            if ( *lhs.array->items(i) = *rhs.array->items(i) ) = 0 then return 0
        next i
    case varType._OBJECT_
        if lhs.object->size <> rhs.object->size then return 0
        for i as integer = 0 to lhs.object->size-1
            if ( *lhs.object->fields(i) = *rhs.object->fields(i) ) = 0 then return 0
        next i
    end select
   
    return -1
end Operator

function array_has overload ( byref arr as variable, byref v as variable ) as integer
   dim as integer res = 0
   if arr.array = 0 then return 0
   for i as integer = 0 to arr.array->size - 1
      if *arr.array->items(i) = v then return i+1
      if arr.array->items(i)->typ = _ARRAY_ then
         res = array_has( *arr.array->items(i), v )
         if res then return res
      end if
   next i
   return res
end function

function array_has overload ( byref arr as variable, byval v as string ) as integer
   dim as integer res = 0
   if arr.array = 0 then return 0
   for i as integer = 0 to arr.array->size - 1
      if arr.array->items(i)->strng = v then return i+1
      if arr.array->items(i)->typ = _ARRAY_ then
         res = array_has( *arr.array->items(i), v )
         if res then return res
      end if
   next i
   return res
end function

function array_has_malformed( byref arr as variable ) as integer
    dim as integer res = 0
    if arr.array = 0 then return 0
    for i as integer = 0 to arr.array->size - 1
        if arr.array->items(i)->typ = _MALFORMED_ then return -1
        if arr.array->items(i)->typ = _ARRAY_ then
            res = array_has_malformed( *arr.array->items(i) )
            if res then return res
        end if
    next i
    return res
end function

Destructor variable()
#IFDEF ___DEBUG
    ? "Variable destructor"
    ? this.tostring
    sleep
#ENDIF
    delete this.object
    delete this.array
end Destructor

sub variable.init( byval s as string, byval n as string = "" )
    dim as integer l = len(s)
    dim as integer arrayIsOpen = 0
    dim as integer objectIsOpen = 0
    dim as integer inQuotes = 0
   
    this.lbl = n

    for i as integer = 0 to l-1
        dim as ubyte c = s[i]

        if isWhite( c ) then continue for
       
        if isNumberJson( c ) then
            if arrayIsOpen or objectIsOpen then
                this.typ = _MALFORMED_
                this.strng = s
                exit sub
            endif

            this.typ = _NUMBER_
            dim as string inNum = ""
           
            Do while IsNumberJson( s[i] )
                inNum += ascii( s[i] )
                if i > l then
                    this.typ = _MALFORMED_
                    this.strng = s
                    ? "Error: i > l"
                    exit sub
                endif
                i+=1
            loop
           
            this.number = val(inNum)
        endif

        if c = 34 then
            if arrayIsOpen or objectIsOpen then
                this.typ = _MALFORMED_
                this.strng = s
                ? "Array / Object is open"
                exit sub
            endif
           
            i+=1
            this.typ = _STRING_
            dim as string inString = ""
            dim as integer done = 0
            Do
                if s[i-1] <> asc("\") then
                    if s[i] <> 34 then
                        inString += ascii( s[i] )
                        i+=1
                    else
                        done = 1
                    endif
                else
                    inString += ascii( s[i] )
                    i+=1
                endif

                if i >= l then
                    this.typ = _MALFORMED_
                    this.strng = s
                    ? "Error: i > l"
                    done = 1
                endif
            loop until done = 1
           
            if inString <> "" then this.strng = unEscape( inString )           
         
            if i <> l-1 then
                this.typ = _MALFORMED_
                this.strng = s
                ? "Error: i <> l-1", i, l-1
                ? instring
            endif
        endif
       
        select case c
            case asc("t"),asc("T"),asc("f"),asc("F"),asc("n"), asc("N")
                if mid(s,i+1,4) = "true" then
                    this.typ = _BOOL_
                    this.bool = _TRUE_
                    i += 3
                elseif mid(s,i+1,4) = "null" then
                    this.typ = _NULL_
                    i += 3
                elseif mid(s,i+1,5) = "false" then
                    this.typ = _BOOL_
                    this.bool = _FALSE_
                    i += 4
                endif
       
            case asc("[")
                arrayIsOpen = 1
                this.typ = _ARRAY_
                this.array = new varArray
                dim as integer level = 1
                dim as string instring = ""
               
                i+=1
                Do
                    dim as ubyte char2 = s[i]
                    dim as variable tmp
                                       
                    select case char2
                       
                        case 34
                            if inQuotes = 0 then inQuotes = 1 else inQuotes = 0
                            instring += ascii( char2 )
                           
                        case asc("[")
                            level += 1
                            instring += "["
                            Do
                                i+=1
                                if s[i] = asc("[") then level += 1
                                if s[i] = asc("]") then level -= 1
                                instring += ascii( s[i] )
                            loop until level = 1
                            if instring <> "" then
                                tmp.init( instring )
                                array->add( @tmp )
                                instring = ""
                            endif
                        case asc("]")
                            if instring <> "" then
                                if isWhite( instring[0] ) = 0 then
                                    tmp.init( instring )
                                    array->add( @tmp )
                                endif
                            endif
                            instring = ""
                            level -= 1
                        case asc(",")
                            if inQuotes = 0 then
                                if instring <> "" then
                                    tmp.init( instring )
                                    array->add( @tmp )
                                    instring = ""
                                endif
                            else
                                instring += ascii( char2 )
                            endif
                        case asc("{")
                            dim as integer olevel = 1
                            instring += "{"
               
                            Do
                                i+=1
                                if s[i] = asc("{") then olevel += 1
                                if s[i] = asc("}") then olevel -= 1
                                instring += ascii( s[i] )
                            loop until olevel = 0
                           
                            if instring <> "" then
                                tmp.init( instring )
                                array->add( @tmp )
                                instring = ""
                            endif
                        case else
                            instring += ascii( char2 )
                           
                    end select
                    i+=1
                loop until level = 0
                arrayIsOpen = 0
           
            case asc("{")
                objectIsOpen = 1
                this.typ = _OBJECT_
                this.object = new varObject
                dim as integer olevel = 1, alevel, inQuotes = 0
                dim as string instring = "", key = ""
                dim as variable tmp
               
                Do
                    i+=1
                    dim as ubyte char2 = s[i]                   
                   
                    if isWhite( char2 ) AND inQuotes = 0 then continue do

                    if inQuotes = 1 then
                        if char2 <> 34 then
                            instring += ascii( char2 )
                            continue do
                        endif
                    endif
                   
                    select case char2                           
                        case asc(":")
                           key = instring
                           instring = ""
                        case asc("[")
                            alevel += 1
                            instring += ascii( char2 )
                        case asc("]")
                            alevel -= 1
                            instring += ascii( char2 )
                        case asc("{")
                            olevel += 1
                            instring += ascii( char2 )
                           
                            Do
                                i+=1
                                char2 = s[i]
                                if char2 = 34 then
                                    if inQuotes = 1 then inQuotes = 0 else inQuotes = 1
                                endif

                                if isWhite( char2 ) and inQuotes = 0 then Continue do                               
                                if char2 = asc("{") then olevel += 1
                                if char2 = asc("}") then olevel -= 1
                                if char2 = asc("[") then alevel += 1
                                if char2 = asc("]") then alevel -= 1
                                instring += ascii( char2 )
                            loop until olevel = 1 and alevel = 0
                           
                            if instring <> "" then
                                tmp.init( instring )
                                object->add( key, @tmp )
                                instring = ""
                            endif                           
                        case asc("}")
                            olevel -= 1
                            if olevel = 0 then
                                if instring <> "" then
                                    tmp.init( instring )
                                    object->add( key, @tmp )
                                    instring = ""
                                endif
                            endif
                        case asc(",")
                            if alevel = 0 then
                                if instring <> "" then
                                    tmp.init( instring )
                                    object->add( key, @tmp )
                                    instring = ""
                                endif
                            else
                                instring += ascii( char2 )
                            endif
                        case 34
                            instring += ascii( char2 )
                            if inQuotes = 1 then inQuotes = 0 else inQuotes = 1

                        case else                       
                            instring += ascii( char2 )
                    end select
                loop until olevel = 0
                objectIsOpen = 0
               
        end select
    next i
   
end sub

function variable.getType() as string
    select case typ
    case _NUMBER_:
        return "Number"
    case _STRING_:
        return "String"
    case _BOOL_:
        return "Boolean"
    case _ARRAY_:
        return "Array"
    case _OBJECT_:
        return "Object"
    case _NULL_:
        return "null"
    case _MALFORMED_:
        return "[MALFORMED]"
    end select
end function

function variable.getTypeNum() as vartype
    return typ
end function

function variable.toString() as string
    select case typ
    case _NUMBER_:
        return number & ""
    case _STRING_:
        return strng
    case _BOOL_:
        if bool then return "true"
        return "false"
    case _ARRAY_:
        return "ARRAY"
    case _OBJECT_:
        return "OBJECT"
    case _NULL_:
        return "null"
    case _MALFORMED_:
        return "[MALFORMED]"
  end select
end function

function variable.getNumber() as double
    if typ <> _NUMBER_ then return 0
    return number
end function

function variable.getString() as string
    if typ <> _STRING_ then return ""
    return strng
end function

function variable.getBoolean() as integer
    if typ <> _BOOL_ then return _FALSE_
    return bool
end function

function variable.getArray() as vararray ptr
    if typ <> _ARRAY_ then return NULL
    return array
end function

function variable.getObject() as varobject ptr
    if typ <> _OBJECT_ then return NULL
    return object
end function

declare function stringize_object( byref v as variable, byval l as integer = 0 ) as string
declare function stringize_array( byref v as variable ) as string

'dim shared as string stringize_string

function stringize_array( byref v as variable ) as string
   if v.typ <> varType._ARRAY_ then return ""
   if v.array = 0 then return ""
   dim as integer length = v.array->size
   
   if length = 0 then return "[]"
   
   var s = "["   
   
   for i as integer = 0 to length - 1
      if v.array->items(i) <> 0 then
         dim as variable tmp = *v.array->items(i)
         select case tmp.typ
                case _ARRAY_    :
                    s += stringize_array( tmp )
            case _STRING_    :
               s += DBLQUOTE
               s += tmp.strng
               s += DBLQUOTE
            case _BOOL_      :
                    s += tmp.toString
            case _NULL_      :
                    s += "null"
            case _NUMBER_   :
                    s &= tmp.number
            case _OBJECT_   :
                    s += stringize_object( tmp )
         end select
      else
         s &= 0
      end if
      if i <> length-1 then s += "," else s += "]"
   next i
   
   return s   
end function

function stringize_object( byref v as variable, byval l as integer = 0 ) as string
   if v.typ <> varType._OBJECT_ then return ""
   if v.object = 0 then return ""
   dim as integer length = v.object->size
   if length = 0 then return ""
   dim as string s
    s += !"\n"
    for i2 as integer = 0 to l : s += !"\t" : next i2
    s += "{"
   
   for i as integer = 0 to length - 1
      var tkey = v.object->fields(i)->key
      s += !"\n\t"
        for i2 as integer = 0 to l : s += !"\t" : next i2
      s += tkey
      if len(tkey) > 6 then s += !":\t" else s+= !":\t\t"
      if v.object->fields(i)->value then
         var tmp = *v.object->fields(i)->value
         select case tmp.typ
            case _ARRAY_    : s += stringize_array( tmp )
            case _BOOL_     : s += tmp.toString
            case _NULL_       : s += "NULL"
            case _NUMBER_   : s &= tmp.number
            case _OBJECT_   : s += stringize_object( tmp, l+1 )
            case _STRING_   :
               s += DBLQUOTE
               s += tmp.strng
               s += DBLQUOTE
         end select
         if i <> length-1 then
            s += ","
         else
            s += !"\n"
            for i2 as integer = 0 to l : s += !"\t" : next i2
            s += "}"
         endif
      end if
   next i
   
   return s
end function

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

dim shared as string fake_json_word
fake_json_word = "{"
fake_json_word += DBLQUOTE + "txt" + DBLQUOTE + ": " + DBLQUOTE + "word" + DBLQUOTE + ","
fake_json_word += DBLQUOTE + "tag_tkns" + DBLQUOTE + ": [""NN""],"
fake_json_word += DBLQUOTE + "phone_tag" + DBLQUOTE + ": " + DBLQUOTE + "(W ER D)" + DBLQUOTE+ ","
fake_json_word += DBLQUOTE + "nsyls" + DBLQUOTE + ": 1,"
fake_json_word += DBLQUOTE + "accent" + DBLQUOTE + ": 1,"
fake_json_word += DBLQUOTE + "tags" + DBLQUOTE + ": [""stuff"",[""nested"",""array""],""more stuff""]"
fake_json_word += "}"

dim as variable v = fake_json_word
? stringize_object( v )
?:?
? stringize_array( *v.object->get("tags")->array->items(1) )
sleep

sleep


'dim as double t
't = timer
'? stringize_array2( dic )
'? timer-t
'sleep
''dim as variable dic2
'dic2.typ = _ARRAY_
'dic2.array = new varArray
'dic2.array->add( @dic )
'? dic2.array->items(0)->array->size
'sleep

'? dic2.array->size
'sleep
fxm
Posts: 9315
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Extended variable destruction

Postby fxm » Apr 09, 2016 18:45

I get no error for the two configurations (without or with 'Extends Object'), and the console printings are exactly the same?
fxm
Posts: 9315
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Extended variable destruction

Postby fxm » Apr 09, 2016 19:28

You are right to test sometime the pointer before 'Delete' it:
- For the two pointer arrays, no problem because by the sizing, they contain only non-null pointers.
- For the 3 elementary pointers, they are not necessarily used.

Code: Select all

Destructor varArray()
    for i as integer = 0 to this.size-1
        delete items(i)
    next
    erase items
End Destructor

Destructor varObject
    for i as integer = 0 to this.size-1
        delete fields(i)
    next i
    erase fields
end Destructor

Destructor varObjectField()
    if value then delete value
End destructor

Destructor variable()
    if array then delete array
    if object then delete object
end Destructor

But that is not mandatory as is noted the documentation:
Calling Delete on a null pointer induces no action.
fxm
Posts: 9315
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Extended variable destruction

Postby fxm » Apr 10, 2016 8:03

Seen from the user, it should be no behavior difference of a destructor for an alone type or for the same type but which 'Extends Object'.
rolliebollocks
Posts: 2655
Joined: Aug 28, 2008 10:54
Location: new york

Re: Extended variable destruction [nevermind]

Postby rolliebollocks » Apr 10, 2016 22:38

I just suck at memory management and understanding when destructors are called and whatnot. I have it working ok now.
fxm
Posts: 9315
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Extended variable destruction

Postby fxm » Apr 11, 2016 10:32

By putting your main code in a Scope block as below, you can better highlight the destructors called during the different procedure callings (when local objects are destroyed at exits of procedures), and those called when the variable 'v' is destroyed (when it goes out of scope):

Code: Select all

.....
dim shared as string fake_json_word
fake_json_word = "{"
fake_json_word += DBLQUOTE + "txt" + DBLQUOTE + ": " + DBLQUOTE + "word" + DBLQUOTE + ","
fake_json_word += DBLQUOTE + "tag_tkns" + DBLQUOTE + ": [""NN""],"
fake_json_word += DBLQUOTE + "phone_tag" + DBLQUOTE + ": " + DBLQUOTE + "(W ER D)" + DBLQUOTE+ ","
fake_json_word += DBLQUOTE + "nsyls" + DBLQUOTE + ": 1,"
fake_json_word += DBLQUOTE + "accent" + DBLQUOTE + ": 1,"
fake_json_word += DBLQUOTE + "tags" + DBLQUOTE + ": [""stuff"",[""nested"",""array""],""more stuff""]"
fake_json_word += "}"

scope
   dim as variable v = fake_json_word
   ? stringize_object( v )
   ?:?
   ? stringize_array( *v.object->get("tags")->array->items(1) )
   print
   print "--- end of scope"
   print
end scope
print
print "--- end of program"
sleep

Return to “General”

Who is online

Users browsing this forum: No registered users and 1 guest