Announcement

Collapse
No announcement yet.

Dynamic Structures in Memory

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Dynamic Structures in Memory

    I'm trying to think of the best way to hold a dynamic (determined at run-time)
    structure in memory. The structure needs to hold small database tables (usually)
    of different types for large numbers of calculations in memory.

    What I need is some sort of dynamic UDT array where I can choose the types at runtime
    but that's not going to happen it seems.

    Before I go playing with all the HEAPALLOC APIs I thought I'd ask if there was
    an easier way to do it, maybe like

    Dim an array of Dwords for use as array pointers
    call function in a loop to dim an array of a X type and pass the pointer back
    ... or would the dimensioned arrays just fall out of scope and leave me with null pointers... ?

    Linked lists are not flexible enough! How is this sort of thing usually done?

    I suppose what I'm after is a dynamic recordset object without the object methods

    I'm all ears to ideas as I gather many of you have done this sort of stuff before.

    Thanks


    ------------------

    Paul Dwyer
    Network Engineer
    Aussie in Tokyo
    (Paul282 at VB-World)

  • #2
    If you mean, "Choose *from a known list of possibilities*" then you can create an array of UNIONs consisting of all the possible types.
    (BTW, a linked list of UNIONs would be fine for this)

    If you mean, "*determine* the structure at run-time," that's different; here you might use an array of delimited strings. (This might also be a good choice in case #1). What I mean is:

    Instead of:
    Code:
    TYPE Foo
       A AS STRING * 20
       B AS LONG
       C AS SINGLE
    END TYPE
    You could use:
    Code:
    X$(1) = "AAA|12345|56.678"
    X$(2) = "BBBB|-9876|1.6234e9"
    With the pipe character delimiting the fields. Use PARSE$ to get values.

    MCM


    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Is this what you is looking for?

      Regards
      Peter
      Code:
      #compile exe
      #dim all
      #register none
      #include "win32api.inc"
       
      declare function malloc(byval iLen as long) as dword
      declare sub free(byval adr as dword)
       
      type MyType
      	nElements as long
      	pData as double pointer
      end type
       
      global double as double
       
      function pbmain
       
      	local i as long, j as long
      	local count as long : count = -1
      	local nElements as long
      	local pMyType as MyType pointer
      	local pData as double pointer
      	dim dat(0) as MyType pointer
       
      	randomize timer
       
      	for i = 0 to 1000
      		' Maybe you need a new MyType
      		if rnd > 0.5 then
      			incr count
      			redim preserve dat(count)
      			' Allocate mem to new MyType
      			pMyType = malloc(len(MyType))
      			if pMyType = 0 then
      				decr count
      				goto ExitProg
      			end if
      			dat(count) = pMyType
      			' Number of elements
      			nElements = 100 * rnd
      			@dat(count).nElements = nElements
      			' Allocate mem to new data
      			pData = malloc(len(double) * nElements)
      			if pData = 0 then
      				free pMyType				
      				decr count
      				goto ExitProg
      			end if
      			@dat(count).pData = pData
       
      			' Fill with data
      			for j = 0 to nElements-1
      				@pData[j] = rnd				
      			next j
       	
      		end if
       
      	next i
       
      	local TotalMem as long
      	for i = 0 to count
      		TotalMem = TotalMem + len(MyType)
      		TotalMem = TotalMem + @dat(i).nElements * len(double)
      	next i
       
      	' Use data
      	nElements = int(@dat(99).nElements / 2)
      	pData     = @dat(99).pData
      	msgbox "Number of MyType's:" + $TAB + $TAB + format$(count+1) + $CR + _
      	       "Number of elements in MyType nr. 100:" + $TAB + format$(@dat(99).nElements) + $CR + _
      	       "Content of element " + format$(nElements) + ":" + $TAB + $TAB + format$(@pData[nElements]) + $CR + _
      		   "Total mem. used (KB):" +$TAB + $TAB + format$(TotalMem / 1024, "#.##")	       
       
      	ExitProg:
       
      	' Free the mem
      	for i = 0 to count
      		free @dat(i).pData
      		free dat(i)
      		dat(i) = 0
      	next i
       
      	msgbox "OK"
       
      end function
       
      function malloc(byval iLen as long) as dword
          function = GlobalAlloc(%GMEM_FIXED or %GMEM_ZEROINIT, iLen)
      end function    
       
      sub free(byval adr as dword)
          GlobalFree adr
      end sub
      ------------------




      [This message has been edited by Peter P Stephensen (edited January 29, 2001).]
      [email protected]
      www.dreammodel.dk

      Comment


      • #4
        Paul,

        I read your post once more and realized that this is maybe more
        what you are looking for

        Regards
        Peter
        Code:
        #compile exe
        #dim all
        #register none
        #include "win32api.inc"
         
        declare function malloc(byval iLen as long) as dword
        declare sub free(byval adr as dword)
         
        type MyType
        	nElements as long
        	cType as long
        	pData as dword
        end type
         
        %LONG = 1
        %DOUBLE = 2
         
        global double as double
        global long as long
         
        function pbmain
         
        	local i as long, j as long
        	local count as long : count = -1
        	local nElements as long, cType as long
        	local pMyType as MyType pointer
        	local pData as double pointer
        	dim dat(0) as MyType pointer
        	local pDouble as double pointer
        	local pLong as long pointer
        	local ElementSize as long
         
        	randomize timer
         
        	for i = 0 to 1000
        		' Maybe you need a new MyType
        		if rnd > 0.5 then
        			incr count
        			redim preserve dat(count)
         			
        			' Allocate mem to new MyType
        			pMyType = malloc(len(MyType))
        			if pMyType = 0 then
        				decr count
        				goto ExitProg
        			end if
        			dat(count) = pMyType
         			
        			' Number of elements
        			nElements = 100 * rnd
        			@dat(count).nElements = nElements
         			
        			' The type:
        			if rnd > 0.5 then
        				@dat(count).cType = %LONG
        				ElementSize = len(long)
        			else
        				@dat(count).cType = %DOUBLE
        				ElementSize = len(double)
        			end if
        
         
        			' Allocate mem to new data
        			pData = malloc(ElementSize * nElements)
        			if pData = 0 then
        				free pMyType				
        				decr count
        				goto ExitProg
        			end if
        			@dat(count).pData = pData
         
        			' Fill with data
        			select case @dat(count).cType
        			case %LONG
        				pLong = pData
        				for j = 0 to nElements-1
        					@pLong[j] = int(rnd*1000)				
        				next j
         
        			case %DOUBLE
        				pDouble = pData
        				for j = 0 to nElements-1
        					@pDouble[j] = rnd
        				next j
        			end select
         	
        		end if
         
        	next i
         
        	local TotalMem as long
        	for i = 0 to count
        		TotalMem = TotalMem + len(MyType)
         
        		select case @dat(count).cType
        		case %LONG   : ElementSize = len(long)
        		case %DOUBLE : ElementSize = len(double)		
        		end select
         
        		TotalMem = TotalMem + @dat(i).nElements * ElementSize
        	next i
         
        	' Use data
        	local DataType as string
         
        	nElements = int(@dat(99).nElements / 2)
        	select case @dat(99).cType
        	case %LONG   
        		DataType = "Long"
        		pLong = @dat(99).pData
        		msgbox "Number of MyType's:" + $TAB + $TAB + $TAB + format$(count+1) + $CR + _
        	       "Number of elements in MyType nr. 100:" + $TAB + $TAB + format$(@dat(99).nElements) + $CR + _
        	       "Data type of elements in MyType nr. 100:" + $TAB + DataType + $CR + _
        	       "Content of element " + format$(nElements) + ":" + $TAB + $TAB + $TAB + format$(@pLong[nElements]) + $CR + _
        		   "Total mem. used (KB):" + $TAB +$TAB + $TAB + format$(TotalMem / 1024, "#.##")	       
         
        	case %DOUBLE 
        		DataType = "Double"
        		pDouble = @dat(99).pData
        		msgbox "Number of MyType's:" + $TAB + $TAB + $TAB + format$(count+1) + $CR + _
        	       "Number of elements in MyType nr. 100:" + $TAB + $TAB + format$(@dat(99).nElements) + $CR + _
        	       "Data type of elements in MyType nr. 100:" + $TAB + DataType + $CR + _
        	       "Content of element " + format$(nElements) + ":" + $TAB + $TAB + $TAB + format$(@pDouble[nElements],"#.#####") + $CR + _
        		   "Total mem. used (KB):" + $TAB +$TAB + $TAB + format$(TotalMem / 1024, "#.##")	       
         
        	end select
         
        	ExitProg:
         
        	' Free the mem
        	for i = 0 to count
        		free @dat(i).pData
        		free dat(i)
        		dat(i) = 0
        	next i
         
        	msgbox "OK"
         
        end function
         
        function malloc(byval iLen as long) as dword
            function = GlobalAlloc(%GMEM_FIXED or %GMEM_ZEROINIT, iLen)
        end function    
         
        sub free(byval adr as dword)
            GlobalFree adr
        end sub
        ------------------
        [email protected]
        www.dreammodel.dk

        Comment


        • #5
          Thank you for those replies,

          I will need a couple of days to absorb what's here.

          Then I'll flood you with questions



          ------------------

          Paul Dwyer
          Network Engineer
          Aussie in Tokyo
          (Paul282 at VB-World)

          Comment


          • #6
            Peter,

            I think I can work with that second code you added, in some ways it is more
            flexible that what I need.

            As I understand it, in DB terms it creates a column centric table
            of dat(i) UDT's as a top row (so to speak) and the column data (elements)
            drop down from there at variable lengths.

            I think if I work from here I'll solve my problem. I can just use
            nElements of the same size though. I might try to turn it on it's side and make it
            row centric for easier access to an entire row rather than an entire column.
            Or I suppose I could just write a ReturnRow function to work with your current
            structure, besides your column centric method would make searching faster.

            Thank you for the code, I was really only after theory rather than code but
            it shows me how easy it is to use dynamic memory, which I haven't had much experience with.



            ------------------

            Paul Dwyer
            Network Engineer
            Aussie in Tokyo
            (Paul282 at VB-World)

            Comment

            Working...
            X