Announcement

Collapse
No announcement yet.

Dynamic Structures in Memory

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

  • Paul Dwyer
    replied
    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)

    Leave a comment:


  • Paul Dwyer
    replied
    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)

    Leave a comment:


  • Peter P Stephensen
    replied
    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
    ------------------

    Leave a comment:


  • Peter P Stephensen
    replied
    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).]

    Leave a comment:


  • Michael Mattias
    replied
    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


    Leave a comment:


  • Paul Dwyer
    started a topic Dynamic Structures in Memory

    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)
Working...
X