Qbasicnews.com
April 12, 2021, 06:33:40 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: Back to Qbasicnews.com | QB Online Help | FAQ | Chat | All Basic Code | QB Knowledge Base
 
   Home   Help Search Login Register  
Pages: [1] 2
  Print  
Author Topic: Dynamic Arrays in User Defined Types  (Read 8025 times)
MystikShadows
Ancient Guru
****
Posts: 542



WWW
« on: March 08, 2005, 08:42:07 AM »

Hi All,

Ok let's say I have the following:

Code:

TYPE SomeType
     Description AS STRING
     Age         AS LONG
END TYPE

TYPE DynamicStructure
     SomeNumber  AS LONG
     SomeName    AS STRING
     SomeArray() AS SomeType
END TYPE



My Quesions are:

1. Can I have a String without a fixed lenght in a User Defined Type like what I'm doing (Knowing that this would be written to a binary file hence no specific structure or length should be needed).

2. Can I have dynamic arrays in User Defined Type definitions like I have here (who's length (ubound) would change elsewhere in the program)?

3. Could I have dymanic arrays of a type that would also have a dynamic array in it's definition?  If so, how many levels deep would be allowed?

Thanks all.
Logged

hen they say it can't be done, THAT's when they call me ;-).




need hosting:  http://www.jc-hosting.net
All about ASCII: http://www.ascii-world.com
lkd85
Member
*
Posts: 63


« Reply #1 on: March 08, 2005, 12:30:11 PM »

Dynamic strings are allowed, but dynamic arrays aren't. The easiest work around is to use a pointer array. This is how C/C++ does it.


Code:


TYPE SomeType
     Description AS STRING
     Age         AS LONG
END TYPE

TYPE DynamicStructure
     SomeNumber  AS LONG
     SomeName    AS STRING
     SomeArray AS SomeType Ptr
END TYPE

Sub Main
Dim test As DynamicStructure

numstructs = 7
test.SomeArray = Allocate(numstructs * Len(SomeType))

For i = 0 To numstructs - 1
    test.SomeArray[i].Description = "" 'Null Dynamic String First!
Next i

test.SomeArray[2].Description = "Drug Dealer"
test.SomeArray[2].Age = 87

For i = 0 To numstructs - 1
Print test.SomeArray[i].Description, test.SomeArray[i].Age
Next i

End Sub

Main

Sleep

Logged
MystikShadows
Ancient Guru
****
Posts: 542



WWW
« Reply #2 on: March 08, 2005, 01:06:31 PM »

Excellent, at least there is a way :-).  Thank you

Now then could I have the following:

Code:

TYPE SomeType
     Description   AS STRING
     ItsID         AS LONG
END TYPE

TYPE DynamicType
     Name          AS STRING
     Number        AS LONG
     DynamicPart   AS SomeType PTR
END TYPE

TYPE CombinedType
     SomeNumber    AS LONG
     SomeName      AS STRING
     WeirdPart     AS DynamicType PTR
END TYPE



Provided I do the proper initialization to everything and allocate what's needed?
Logged

hen they say it can't be done, THAT's when they call me ;-).




need hosting:  http://www.jc-hosting.net
All about ASCII: http://www.ascii-world.com
VonGodric
Ancient Guru
****
Posts: 674



WWW
« Reply #3 on: March 08, 2005, 01:55:53 PM »

btw if you have unfixed lenght strings in the udt's then you need to deinit them manually -or you'll have memory leaks.

with yourtype.stringfield = ""
Logged

url]http://fbide.sourceforge.net/[/url]
lkd85
Member
*
Posts: 63


« Reply #4 on: March 08, 2005, 01:58:20 PM »

Yep.

Code:

TYPE SomeType
     Description   AS STRING
     ItsID         AS LONG
END TYPE

TYPE DynamicType
     Name          AS STRING
     Number        AS LONG
     DynamicPart   AS SomeType PTR
END TYPE

TYPE CombinedType
     SomeNumber    AS LONG
     SomeName      AS STRING
     WeirdPart     AS DynamicType PTR
END TYPE

Sub Main
Dim ct As CombinedType

numdt = 9
ct.WeirdPart = Allocate(numdt * Len(DynamicType))

numst = 7
For i = 0 To numdt - 1
    ct.WeirdPart[i].DynamicPart = Allocate(numst * Len(SomeType))
    For j = 0 To numst - 1
        ct.WeirdPart[i].DynamicPart[j].Description = ""
    Next j
Next i

With ct.WeirdPart[3]
.DynamicPart[5].Description = "Menace"
.DynamicPart[2].Description = "Person Unknown"
Print .DynamicPart[5].Description, .DynamicPart[2].Description
End With

With ct.WeirdPart[7]
.DynamicPart[5].Description = "Goody - Two - Shoes"
.DynamicPart[2].Description = "Apathetic"
Print .DynamicPart[5].Description, .DynamicPart[2].Description
End With

End Sub

Main
Sleep
Logged
v3cz0r
I hold this place together
*****
Posts: 924



WWW
« Reply #5 on: March 08, 2005, 06:18:47 PM »

Always use Callocate() as Allocate() won't clear the contents, so if you do bar->foo = "" (foo being a dyn string), if the contens of foo (the descriptor) aren't 0'ed, the rtlib will try to free an invalid pointer.
Logged

MystikShadows
Ancient Guru
****
Posts: 542



WWW
« Reply #6 on: March 08, 2005, 07:39:18 PM »

What if I might need to change the number of elements in those PTR things should I use CAlliocate there to? or Allocate if I want what's there to stay preserved so to speak?
Logged

hen they say it can't be done, THAT's when they call me ;-).




need hosting:  http://www.jc-hosting.net
All about ASCII: http://www.ascii-world.com
DrV
Na_th_an
*****
Posts: 1553



WWW
« Reply #7 on: March 08, 2005, 08:43:27 PM »

Reallocate

* points at C realloc() function *
Logged
Dr_Davenstein
Na_th_an
*****
Posts: 2052


« Reply #8 on: March 08, 2005, 10:50:30 PM »

This raises a question for me too...

I have no experience with pointers. :roll:

Is it possible to allocate memory for these variables on the fly?

Code:

Type ObjType
 IdNum as Integer
 VertCnt as Integer
 FaceCnt as Integer
 Num_Surfaces as Integer
 Start_Id(1 to 50) as Integer
 End_Id(1 to 50) as Integer
 Surface_Id(1 to 50) as Integer
 Transparent(1 to 50) as BYTE
 Textured(1 to 50) as Byte
 Collidable(1 to 50) as Byte
 RGBA(1 to 25, 3) as Single  
 Ambient(1 to 50, 3) as Single
 Diffuse(1 to 50, 3) as Single
 Specular(1 to 50, 3) as Single
 Emission(1 to 50, 3) as Single
 Shininess(1 to 50) as Single
 Angle_X as Integer
 Angle_Y as Integer
 Angle_Z as Integer
 IsDynamic as Byte
 Trans as Vector3DType
 TransSpd as Vector3DType
 Num_Targets as Integer
 CurTarg as Integer
 Target(1 to 10) as Vector3DType
 TargSpd(1 to 10) as Vector3DType
End Type

Dim Entity(1 to Total_Entities) as ObjType



Basically, all the arrays that have 50 members...
Code:

Start_Id(1 to 50) as Integer
End_Id(1 to 50) as Integer
Surface_Id(1 to 50) as Integer


..need to be allocated to Num_Surfaces instead of 50, but I don't know how to do it. Is it even possible to do that using pointers, and how confusing would the code be? This isn't all either... I have alot of stuff in my program that would benefit from this. If it's even possible that is. Wink
Logged
lkd85
Member
*
Posts: 63


« Reply #9 on: March 08, 2005, 11:57:26 PM »

Yea! In fact that's how the Quake 2 MD2 structs work. Basically you would do this.

Code:

Type Vertex
x As Single
y As Single
z As Single
End Type

Type Tri
verts(2) As Vertex
End Type

Type Obj
numoftris As Integer
tris As Tri Ptr
End Type

Dim tobj As Obj

tobj.numoftris = 100

tobj.tris = Callocate(tobj.numoftris * Len(Tri))\

tobj.tris[10].verts(0).x = 194.415 'Access array using brackets []



You can do that for any struct you have. That's a LOT easier than having id's to arrays if I'm reading your post correctly. Read the above posts too.
Logged
Dr_Davenstein
Na_th_an
*****
Posts: 2052


« Reply #10 on: March 09, 2005, 12:47:05 AM »

So, I could do it like this?


Code:

Type ObjType
 Num_Surfaces as Integer
 Start_Id as Integer ptr
 End_Id as Integer ptr
 Surface_Id as Integer ptr
End Type

Dim Entity(1 to Total_Entities) as ObjType

Sub LoadOBJ(Entity as ObjType)

 'Get Entity.Num_Surfaces from file...
  Entity.Start_Id=Callocate(Entity.Num_Surfaces*Len(Entity.Start_Id))
End Sub


Then when I want to use the new array in a sub...

Code:
Sub Draw_Entity( Entity as ObjType)
 
 For S = 1 to Entity.Num_Surfaces
  For P = Entity.Start_Id[S] to Entity.End_Id[S]
   
  Next
 Next
End Sub


Does that look right?


EDIT:
Ok, that seems to work good, but what about these?

 
Code:

 RGBA(1 to 50, 3) as Single ''heh oops!
 Ambient(1 to 50, 3) as Single
 Diffuse(1 to 50, 3) as Single
 Specular(1 to 50, 3) as Single
 Emission(1 to 50, 3) as Single


How do I allocate a matrix in this method?


Would I just do something like this?


Code:
Type Surface_Properties_Type
 RGBA(3) as Single ''heh oops!
 Ambient(3) as Single
 Diffuse(3) as Single
 Specular(3) as Single
 Emission(3) as Single
End Type


Type ObjType
 Num_Surfaces as Integer
 Start_Id as Integer ptr
 End_Id as Integer ptr
 Surface_Id as Integer ptr
 Surface_Properties as Surface_Properties_Type ptr
End Type

Dim Entity(1 to Total_Entities) as ObjType



Then....


Code:

Some_Sub(Entity as ObjType)

 Entity.Surface_Properties =  Callocate(Entity.Num_Surfaces*Len(Entity.Surface_Properties))

End Sub


Some_Other_Sub(Entity as ObjType)

 Entity.Surface_Properties[S].RGBA(1) = 'Get From File

End Sub




It's kinda hard to get used to... Is it even right?
Logged
lkd85
Member
*
Posts: 63


« Reply #11 on: March 09, 2005, 01:55:58 AM »

Pretty much, although you need to subtract 1 from the Num_Surfaces

Code:

 For S = 1 to Entity.Num_Surfaces  - 1
Logged
Dr_Davenstein
Na_th_an
*****
Posts: 2052


« Reply #12 on: March 09, 2005, 03:36:01 AM »

One more question... Tongue

Do I need to deallocate these, or will it be automatic? I've tested a few things and I didn't notice any memory leaks... at least this Ram-Booster thing I'm using didn't report any...

Is it automatic deallocation when the program ens then?
Logged
Sterling Christensen
Na_th_an
*****
Posts: 1328


« Reply #13 on: March 09, 2005, 04:30:06 AM »

Quote from: "Dr_Davenstein"
Is it automatic deallocation when the program ens then?

Windows might do that, but I'm pretty sure you're supposed to deallocate them.
Logged
MystikShadows
Ancient Guru
****
Posts: 542



WWW
« Reply #14 on: March 09, 2005, 06:43:55 AM »

All this raised another question.  Here's a piece of code:

Code:

TYPE SomeType
     ThisField  AS LONG
     ThisOtherField AS STRING  
END TYPE

' Static array for the sake of test, but
' Question would apply to dynamic arrays
' declared like this too.
DIM ThisArray(1 to 100) AS SomeType
DIM Sorted(1 to 100)    AS SomeType

' Assuming I have a function I did called SortArray()
Sorted = SortArray(ThisArray())



Can I do this?  Or, do I need to pass the address of ThisArray like with the @ symbol ?
Logged

hen they say it can't be done, THAT's when they call me ;-).




need hosting:  http://www.jc-hosting.net
All about ASCII: http://www.ascii-world.com
Pages: [1] 2
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!