Seite 1 von 1

DynamicMemory

Verfasst: 22.07.2011 00:10
von CSHW89
Hi Leute,
für mein aktuelles Projekt hab ich mir eine Include geschrieben, die man eigentlich immer wieder mal gebrauchen könnte: DynamicMemory
Sie hat zwei Funktionen: Sie aktuallisiert nach jedem Lesen bzw. Schreiben im Speicherblock die Position, an der danach gelesen bzw. geschrieben wird (je nach Länge der Daten), und sie vergrößert ggf. den Speicherblock, wenn er nicht mehr ausreicht. Das ist halt dann besonders hilfreich, wenn man eine Menge Daten in einen Speicherblock schreiben will, man aber vorher nicht weiß, wie groß er sein muss.
Die Include ist im OOP-Style geschrieben. DYMMemory ist das Interface, dieses hat viele Funktionen der MemoryLib, wie Peek und Poke. Mit DYMNewMemory() erzeugt man ein neuen Speicherblock, mit *dym\free() gibt man ihn wieder frei.

Hier ein Beispielcode:

DynamicMemoryTest.pb

Code: Alles auswählen

IncludeFile "DynamicMemory.pbi"

Define *dym.DYMMemory
Define size, *memory

; write new memory block
*dym = DYMNewMemory()
*dym\PokeI(0)  ; reserved for the size
For i = 0 To 9
  *dym\PokeI(i)
Next
*dym\PokeS("Hello World!")
*dym\fill(5,42)

; save the size
*dym\setPosition(0)
*dym\PokeI(*dym\getSize())

If CreateFile(0, GetTemporaryDirectory()+"DynamicMemoryTest")
  WriteData(0, *dym\getMemory(), *dym\getSize())
  CloseFile(0)
EndIf

*dym\free()


; read the memory block
If ReadFile(0, GetTemporaryDirectory()+"DynamicMemoryTest")
  size = ReadInteger(0)
  *memory = AllocateMemory(size)
  FileSeek(0, 0)
  ReadData(0, *memory, size)
  
  *dym = DYMNewMemory(*memory)
  *dym\PeekI()
  For i = 0 To 9
    Debug *dym\PeekI()
  Next
  Debug *dym\PeekS()
  For i = 0 To 4
    Debug *dym\PeekB()
  Next
  
  CloseFile(0)
EndIf

Und hier die Include:

DynamicMemory.pbi:

Code: Alles auswählen

; Name: DynamicMemory
; Author: Kevin Jasik (CSHW89)
; Date: 21.07.2011


Structure DYMValue
  StructureUnion
    byte.b
    word.w
    long.l
    float.f
    quad.q
    double.d
    character.c
    ascii.a
    unicode.c
    integer.i
  EndStructureUnion
EndStructure

Structure DYMMemoryObj
  *VTable
  *memory
  *pos.DYMValue
  size.i
EndStructure


Interface DYMMemory
  free()
  PokeB(byte.b)
  PokeW(word.w)
  PokeL(long.l)
  PokeF(float.f)
  PokeQ(quad.q)
  PokeD(double.d)
  PokeC(character.c)
  PokeA(ascii.a)
  PokeU(unicode.u)
  PokeI(integer.i)
  PokeS(string.s, length.i = -1, format.i = 0)
  PeekB.b()
  PeekW.w()
  PeekL.l()
  PeekF.f()
  PeekQ.q()
  PeekD.d()
  PeekC.c()
  PeekA.a()
  PeekU.u()
  PeekI.i()
  PeekS.s(length.i = -1, format.i = 0)
  copy(*source, length.i)
  move(*source, length.i)
  fill(size.i, value.i = 0, type.i = 0)
  getMemory.i()
  getPosition.i()
  setPosition(position.i)
  movePosition(move.i)
  getSize.i()
  expand(size.i)
EndInterface


; Free the memory previously allocated with DYMNewMemory
; and the dinamic-memory-object *dym

Procedure DYMFreeMemory(*dym.DYMMemoryObj)
  FreeMemory(*dym\memory)
  FreeMemory(*dym)
EndProcedure


Macro DYMCheckExpandMemory(_bytes_)
  Protected position.i, newSize.i
  Protected *savemem
  
  ; relative position to the memory
  position = *dym\pos - *dym\memory
  
  ; while the space is not enough
  While (position + _bytes_ >= *dym\size)
    
    newSize = *dym\size * 2
    *savemem = *dym\memory
    *dym\memory = ReAllocateMemory(*dym\memory, newSize)
    
    If (*dym\memory = #Null)
      *dym\memory = *savemem
      ProcedureReturn #False
    EndIf
    
    ; set the new position, because the memory may be different
    *dym\pos  = *dym\memory + position
    *dym\size = newSize
  Wend
EndMacro


; Writes a byte number to the dynamic-memory-object
; If space is not enough, the memory will be expanded automatically

Procedure DYMPokeB(*dym.DYMMemoryObj, byte.b)
  DYMCheckExpandMemory(SizeOf(Byte))
  *dym\pos\byte = byte
  *dym\pos + SizeOf(Byte)
  ProcedureReturn #True
EndProcedure


; Writes a word number to the dynamic-memory-object
; If space is not enough, the memory will be expanded automatically

Procedure DYMPokeW(*dym.DYMMemoryObj, word.w)
  DYMCheckExpandMemory(SizeOf(Word))
  *dym\pos\word = word
  *dym\pos + SizeOf(Word)
  ProcedureReturn #True
EndProcedure


; Writes a long number to the dynamic-memory-object
; If space is not enough, the memory will be expanded automatically

Procedure DYMPokeL(*dym.DYMMemoryObj, long.l)
  DYMCheckExpandMemory(SizeOf(Long))
  *dym\pos\long = long
  *dym\pos + SizeOf(Long)
  ProcedureReturn #True
EndProcedure


; Writes a float number to the dynamic-memory-object
; If space is not enough, the memory will be expanded automatically

Procedure DYMPokeF(*dym.DYMMemoryObj, float.f)
  DYMCheckExpandMemory(SizeOf(Float))
  *dym\pos\float = float
  *dym\pos + SizeOf(Float)
  ProcedureReturn #True
EndProcedure


; Writes a quad number to the dynamic-memory-object
; If space is not enough, the memory will be expanded automatically

Procedure DYMPokeQ(*dym.DYMMemoryObj, quad.q)
  DYMCheckExpandMemory(SizeOf(Quad))
  *dym\pos\quad = quad
  *dym\pos + SizeOf(Quad)
  ProcedureReturn #True
EndProcedure


; Writes a double number to the dynamic-memory-object
; If space is not enough, the memory will be expanded automatically

Procedure DYMPokeD(*dym.DYMMemoryObj, double.d)
  DYMCheckExpandMemory(SizeOf(Double))
  *dym\pos\double = double
  *dym\pos + SizeOf(Double)
  ProcedureReturn #True
EndProcedure


; Writes a character number to the dynamic-memory-object
; If space is not enough, the memory will be expanded automatically

Procedure DYMPokeC(*dym.DYMMemoryObj, character.c)
  DYMCheckExpandMemory(SizeOf(Character))
  *dym\pos\character = character
  *dym\pos + SizeOf(Character)
  ProcedureReturn #True
EndProcedure


; Writes an ascii character to the dynamic-memory-object
; If space is not enough, the memory will be expanded automatically

Procedure DYMPokeA(*dym.DYMMemoryObj, ascii.a)
  DYMCheckExpandMemory(SizeOf(Ascii))
  *dym\pos\ascii = ascii
  *dym\pos + SizeOf(Ascii)
  ProcedureReturn #True
EndProcedure


; Writes an unicode character to the dynamic-memory-object
; If space is not enough, the memory will be expanded automatically

Procedure DYMPokeU(*dym.DYMMemoryObj, unicode.u)
  DYMCheckExpandMemory(SizeOf(Unicode))
  *dym\pos\unicode = unicode
  *dym\pos + SizeOf(Unicode)
  ProcedureReturn #True
EndProcedure


; Writes an integer number to the dynamic-memory-object
; If space is not enough, the memory will be expanded automatically

Procedure DYMPokeI(*dym.DYMMemoryObj, integer.i)
  DYMCheckExpandMemory(SizeOf(integer))
  *dym\pos\integer = integer
  *dym\pos + SizeOf(Integer)
  ProcedureReturn #True
EndProcedure


; Writes a string (including the ending '0') to the dynamic-memory-object
; If space is not enough, the memory will be expanded automatically

Procedure DYMPokeS(*dym.DYMMemoryObj, string.s, length.i = -1, format.i = 0)
  Protected size.i
  
  If (length > -1)
    string = Left(string, length)
  EndIf
  
  size = StringByteLength(string+" ", format)
  
  DYMCheckExpandMemory(size)
  PokeS(*dym\pos, string, -1, format)
  *dym\pos + size
  ProcedureReturn #True
EndProcedure


; Reads a byte number from the dynamic-memory-object

Procedure.b DYMPeekB(*dym.DYMMemoryObj)
  Protected byte.b
  
  byte = *dym\pos\byte
  *dym\pos + SizeOf(Byte)
  
  ProcedureReturn byte
EndProcedure


; Reads a word number from the dynamic-memory-object

Procedure.w DYMPeekW(*dym.DYMMemoryObj)
  Protected word.w
  
  word = *dym\pos\word
  *dym\pos + SizeOf(Word)
  
  ProcedureReturn word
EndProcedure


; Reads a long number from the dynamic-memory-object

Procedure.l DYMPeekL(*dym.DYMMemoryObj)
  Protected long.l
  
  long = *dym\pos\long
  *dym\pos + SizeOf(Long)
  
  ProcedureReturn long
EndProcedure


; Reads a float number from the dynamic-memory-object

Procedure.f DYMPeekF(*dym.DYMMemoryObj)
  Protected float.f
  
  float = *dym\pos\float
  *dym\pos + SizeOf(Float)
  
  ProcedureReturn float
EndProcedure


; Reads a quad number from the dynamic-memory-object

Procedure.q DYMPeekQ(*dym.DYMMemoryObj)
  Protected quad.q
  
  quad = *dym\pos\quad
  *dym\pos + SizeOf(Quad)
  
  ProcedureReturn quad
EndProcedure


; Reads a double number from the dynamic-memory-object

Procedure.d DYMPeekD(*dym.DYMMemoryObj)
  Protected double.d
  
  double = *dym\pos\double
  *dym\pos + SizeOf(Double)
  
  ProcedureReturn double
EndProcedure


; Reads a character number from the dynamic-memory-object

Procedure.c DYMPeekC(*dym.DYMMemoryObj)
  Protected character.c
  
  character = *dym\pos\character
  *dym\pos + SizeOf(Character)
  
  ProcedureReturn character
EndProcedure


; Reads an ascii character from the dynamic-memory-object

Procedure.a DYMPeekA(*dym.DYMMemoryObj)
  Protected ascii.a
  
  ascii = *dym\pos\ascii
  *dym\pos + SizeOf(Ascii)
  
  ProcedureReturn ascii
EndProcedure


; Reads an unicode character from the dynamic-memory-object

Procedure.u DYMPeekU(*dym.DYMMemoryObj)
  Protected unicode.u
  
  unicode = *dym\pos\unicode
  *dym\pos + SizeOf(Unicode)
  
  ProcedureReturn unicode
EndProcedure


; Reads an integer number from the dynamic-memory-object

Procedure.i DYMPeekI(*dym.DYMMemoryObj)
  Protected integer.i
  
  integer = *dym\pos\integer
  *dym\pos + SizeOf(Integer)
  
  ProcedureReturn integer
EndProcedure


; Reads a string from the dynamic-memory-object
; The string should be ended by a '0' character, else it
; will read the memory until a '0' character is encounter.

Procedure.s DYMPeekS(*dym.DYMMemoryObj, length.i = -1, format.i = 0)
  Protected string.s
  
  string = PeekS(*dym\pos, length, format)
  *dym\pos + StringByteLength(string, format)
  
  If (length < 0)
    *dym\pos + StringByteLength(" ", format)
  EndIf
  
  ProcedureReturn string
EndProcedure


; Copy a memory area starting from the *source
; to the dynamic-memory-object with the spcified length
; If space is not enough, the memory will be expanded automatically

Procedure DYMCopyMemory(*dym.DYMMemoryObj, *source, length.i)
  DYMCheckExpandMemory(length)
  
  CopyMemory(*source, *dym\pos, length)
  *dym\pos + length
  ProcedureReturn #True
EndProcedure


; Copy a memory area starting from the *source
; to the dynamic-memory-object with the spcified length
; If space is not enough, the memory will be expanded automatically

Procedure DYMMoveMemory(*dym.DYMMemoryObj, *source, length.i)
  DYMCheckExpandMemory(length)
  
  MoveMemory(*source, *dym\pos, length)
  *dym\pos + length
  ProcedureReturn #True
EndProcedure


Procedure DYMFillMemory(*dym.DYMMemoryObj, size.i, value.i = 0, type.i = 0)
  DYMCheckExpandMemory(size)
  
  FillMemory(*dym\pos, size, value, type)
  *dym\pos + size
  ProcedureReturn #True
EndProcedure


; Returns the memory that was allocated
; to the dynamic-memory-object

Procedure DYMGetMemory(*dym.DYMMemoryObj)
  ProcedureReturn *dym\memory
EndProcedure


; Returns the relative position to the memory

Procedure DYMGetPosition(*dym.DYMMemoryObj)
  ProcedureReturn *dym\pos - *dym\memory
EndProcedure


; Sets the relative position of the memory

Procedure DYMSetPosition(*dym.DYMMemoryObj, position.i)
  *dym\pos = *dym\memory + position
EndProcedure


Procedure DYMMovePosition(*dym.DYMMemoryObj, move.i)
  *dym\pos + move
EndProcedure


Procedure DYMGetSize(*dym.DYMMemoryObj)
  ProcedureReturn *dym\size
EndProcedure


Procedure DYMExpandMemory(*dym.DYMMemoryObj, size.i)
  Protected position.i, newSize.i
  
  position = *dym\pos - *dym\memory
  newSize  = *dym\size + size
  
  *dym\memory = ReAllocateMemory(*dym\memory, newSize)
  *dym\pos  = *dym\memory + position
  *dym\size = newSize
  
  ProcedureReturn newSize
EndProcedure


; Create a new dynamic-memory-object
; and allocates a contiguous memory area
; @param: size is an optional parameter
;  It is the initial size of the memory

Procedure DYMNewMemory(*memory=#Null, size=512)
  Protected *dym.DYMMemoryObj
  
  If (size <= 0) And (*memory = #Null)
    ; wrong parameter
    ; return error of the original function
    ProcedureReturn AllocateMemory(size)
  EndIf
  ; new dynamic-memory-object
  *dym = AllocateMemory(SizeOf(DYMMemoryObj))
  
  If (*dym <> #Null)
    ; set the virtual function table
    *dym\VTable = ?DYMMemoryFunction
    
    ; initialize memory
    If (*memory <> #Null)
      *dym\memory = *memory
    Else
      *dym\memory = AllocateMemory(size)
    EndIf
    If (*dym\memory = #Null)
      FreeMemory(*dym)
      ProcedureReturn #Null
    EndIf
    
    ; set the current position to the start of the memory
    ; (relative position is 0)
    *dym\pos  = *dym\memory
    *dym\size = size
  EndIf
  
  ProcedureReturn *dym
  
  DataSection
    DYMMemoryFunction:
    Data.i @DYMFreeMemory()
    Data.i @DYMPokeB()
    Data.i @DYMPokeW()
    Data.i @DYMPokeL()
    Data.i @DYMPokeF()
    Data.i @DYMPokeQ()
    Data.i @DYMPokeD()
    Data.i @DYMPokeC()
    Data.i @DYMPokeA()
    Data.i @DYMPokeU()
    Data.i @DYMPokeI()
    Data.i @DYMPokeS()
    Data.i @DYMPeekB()
    Data.i @DYMPeekW()
    Data.i @DYMPeekL()
    Data.i @DYMPeekF()
    Data.i @DYMPeekQ()
    Data.i @DYMPeekD()
    Data.i @DYMPeekC()
    Data.i @DYMPeekA()
    Data.i @DYMPeekU()
    Data.i @DYMPeekI()
    Data.i @DYMPeekS()
    Data.i @DYMCopyMemory()
    Data.i @DYMMoveMemory()
    Data.i @DYMFillMemory()
    Data.i @DYMGetMemory()
    Data.i @DYMGetPosition()
    Data.i @DYMSetPosition()
    Data.i @DYMMovePosition()
    Data.i @DYMGetSize()
    Data.i @DYMExpandMemory()
  EndDataSection
EndProcedure
lg Kevin

Re: DynamicMemory

Verfasst: 22.07.2011 00:57
von STARGÅTE
Nett, aber ich glaube das viele schon sowas in der Art haben^^ (zumindest ich)

Zumindest was das, dass erste was ich genmacht habe als ich Peek() und Poke() sah: Es in von der File-Lib bekannte Funktionen zu schreiben.

[LeichtOfftopic]
Vielleicht schaffst du aber jetzt das, wo andere dran scheitern:
Ein "echtes" WriteStructure() bzw PokeStructure() zu schreiben, welches die gleichen Parameter bekommt wie zB ClearStructure usw.

Damit meine ich, ein unkompliziertes Auslesen einer ganze Struktur (mit Strings, Lists, Arrays, Maps,usw.):

Hier mal ein Anfang wo ich dann stehen geblieben bin:
GetArrayStructureData() ; Gibt den aufbau der Struktur eines Arrays zurück (als Text)

Code: Alles auswählen

Structure StructureData
	StructureUnion
		Position.i
		Type.i
	EndStructureUnion
	StructureUnion
		ArraySize.i 
		ListPosition.i
	EndStructureUnion	
	StructureUnion
		ArrayPosition.i
		ListStructureSize.i
	EndStructureUnion
	StructureUnion
		SubStructureSize.i
		AData.i
		*ListStructureData
	EndStructureUnion
	*SubStructureData
	Laber.i
EndStructure



#StructureData_String   =  0 
#StructureData_End      = -1
#StructureData_FixArary = -2
#StructureData_Sub      = -3
#StructureData_Array    = -4
#StructureData_List     = -5
#StructureData_Map      = -6

Procedure.s GetStructureData_Proc(*StructureData.StructureData, StructureSize)
	Protected String$, Buffer, CurrentPosition
	With *StructureData
		While *StructureData And \Type <> #StructureData_End
			If String$ : String$ + ", " : EndIf
			Select \Type
				Case #StructureData_List
					Buffer = \ListPosition - CurrentPosition
					If Buffer : String$ + "Data["+Str(Buffer)+"], " : EndIf
					String$ + "List{"+GetStructureData_Proc(\ListStructureData, \ListStructureSize)+"}"
					CurrentPosition + Buffer + 8
					*StructureData + SizeOf(StructureData)-4
				Case #StructureData_Map
					Buffer = \ListPosition - CurrentPosition
					If Buffer : String$ + "Data["+Str(Buffer)+"], " : EndIf
					String$ + "Map{"+GetStructureData_Proc(\ListStructureData, \ListStructureSize)+"}"
					CurrentPosition + Buffer + 4
					*StructureData + SizeOf(StructureData)-4
				Case #StructureData_Array
					Buffer = \ListPosition - CurrentPosition
					If Buffer : String$ + "Data["+Str(Buffer)+"], " : EndIf
					If \AData > 1
						String$ + "Array(" + Str(\AData) + "){"
						String$ + GetStructureData_Proc(\Laber, \ListStructureSize)
						String$ + "} "
					Else
						String$ + GetStructureData_Proc(\Laber, \ListStructureSize)
					EndIf
					CurrentPosition + Buffer +4
					*StructureData + SizeOf(StructureData)
				Case #StructureData_FixArary
					Buffer = \ArrayPosition - CurrentPosition
					If Buffer : String$ + "Data["+Str(Buffer)+"], " : EndIf
					If \ArraySize > 1
						String$ + "Sub(" + Str(\ArraySize) + "){"
						String$ + GetStructureData_Proc(\SubStructureData, \SubStructureSize)
						String$ + "} "
					Else
						String$ + GetStructureData_Proc(\SubStructureData, \SubStructureSize)
					EndIf
					CurrentPosition + Buffer + \ArraySize * \SubStructureSize
					*StructureData + SizeOf(StructureData)-4
				Case #StructureData_Sub
					Buffer = \ListPosition - CurrentPosition
					If Buffer : String$ + "Data["+Str(Buffer)+"], " : EndIf
					String$ + GetStructureData_Proc(\ListStructureData, \ListStructureSize)
					CurrentPosition + Buffer + \ListStructureSize
					*StructureData + SizeOf(StructureData)-8
				Default
					Buffer = \Position - CurrentPosition
					If Buffer : String$ + "Data["+Str(Buffer)+"], " : EndIf
					String$ + "String"
					CurrentPosition + Buffer + SizeOf(String)
					*StructureData + SizeOf(Integer)
			EndSelect
		Wend
		Buffer = StructureSize - CurrentPosition
		If String$ : String$ + ", " : EndIf
		If Buffer : String$ + "Data["+Str(Buffer)+"]" : EndIf
	EndWith
	ProcedureReturn String$
EndProcedure

Macro GetArrayStructureData(ArrayName, StructureName)
	GetStructureData_Proc(PeekI(@ArrayName-16), SizeOf(StructureName))
EndMacro


;- Beispiel

Structure SubComplex
	Long.l
	String.s
	Map Words.w()
	Float.f
EndStructure

Structure Complex
	Long.l
	Byte.b
	String.s
	FixArray.c[7]
	FisString.s{3}
	Array ComplexArray.SubComplex(40)
	Double.d
	List ComplexList.SubComplex()
	Complex.SubComplex
EndStructure

Dim Beispiel.Complex(1)

Debug GetArrayStructureData(Beispiel(), Complex)
Wie du siehst kann ich durchaus ohne Probleme den Aufbau lesen und somit auch in einen Speicher schreiben.

Ich bin jedoch dann dran geschreitern, das es keine möglichkeit gibt, Lists, Maps usw. zu füllen, wenn man nur den Pointer kennt, aber nicht den Namen ...
[/LeichtOfftopic]

Re: DynamicMemory

Verfasst: 22.07.2011 01:06
von CSHW89
Naja bei meiner Include ging es nicht unbedingt um das, mit der Position, sondern eher um das dynamische Erweitern des Blocks. Aber hab ja nicht gesagt, dass meine Include weltbewegend ist <)

Hm, Array, List und Map müsste eigentlich gehen. Hab ja auch in PBScript Routinen drin, um alles mit Arrays und Listen zu machen, ohne sie jemals mit 'Dim' oder 'NewList' erstellt zu haben. Maps hab ich mir noch nicht angeguckt, wollt ich aber auch mal i-wann.
Vielleicht wenn ich mal mehr Zeit hab ;).

lg kevin

Re: DynamicMemory

Verfasst: 22.07.2011 07:44
von ullmann
@CSHW89: Hmm,

schaue ich so auf deinen Code, kommen mir 2 Fragen:

1. Bei jedem ReAllocateMemory wird die Größe verdoppelt. Da fällt mir das Schachbrett mit den Reiskörnern ein, wo die Reismenge durch
Verdoppeln ganz schnell ins Utopische wächst. Wären nicht einige feste Werte für die Vergrößerung sinnvoller, z.B. abhängig von der
Anforderung, z.B. wenn ich 1 KB benötige, dass dann 2 oder 3 KB zusätzlich reserviert werden? Habe ich bei deinem Code bereits 300 MB
reserviert, kommen durch die neue Reservierung nochmal 300 MB dazu, auch wenn ich nur 10 KB benötige.

2. Ich sehe keine Fehlerüberprüfung, ob ReAllocateMemory erfolgreich war.

Code: Alles auswählen

  While (position + _bytes_ >= *dym\size)
    
    newSize = *dym\size * 2
    *dym\memory = ReAllocateMemory(*dym\memory, newSize)
    
    ; set the new position, because the memory may be different
    *dym\pos  = *dym\memory + position
    *dym\size = newSize
  Wend
Gruß

Re: DynamicMemory

Verfasst: 22.07.2011 11:15
von STARGÅTE
@ullmann zu 1.

Aber wie soll dann "der Code" wissen, wie er am bessten den Speicher erweitert.
Denn wenn die Erweiterung wirklich nur auf einen Festen Wert wie 10KB gesetzt wird, und es kommen doch zu den 300MB noch mal 300MB dazu, dann würde er 10.000 mal ReAllocateMemory() ausführen und u.u. fast jedes mal den kompletten Speicher verschieden weil kein Platz mehr da ist.

Es ist also die Frage, was man bevorzugt: Zeit oder Platz, nur eins geht!

Re: DynamicMemory

Verfasst: 22.07.2011 12:01
von CSHW89
zu 1:
Ja, wie Stargate schon sagte, da muss man einfach abwiegen, ob Zeit oder Platz. Aber eine Vergrößerung in Abhängigkeit der bisherigen Größe ist eigentlich normal, vielleicht nicht so drastisch um den Faktor 2. Da kann man von mir aus auch '* 3 / 2' schreiben.

zu 2:
Hm ja, stimmt. Ist gefixed. Die Poke-Funktionen geben 0 zurück, wenn ReAllocateMemory nicht erfolgreich war, ansonsten 1.

lg kevin

Re: DynamicMemory

Verfasst: 22.07.2011 13:09
von ullmann
Mal ein Beispiel:

Man liest eine Datei mit der Größe 2 GB + 1 Word wordweise in den Speicher ein. Wenn 2 GB Speicher voll geschrieben sind, werden durch das eine Word nochmals 2 GB Speicher dazu reserviert, in der Summe sind das 4 GB, was jeden XP-Rechner an seine Grenzen bringt.

Die Verdopplung ist schon gut, damit es bei kleineren Werten schnell wächst, aber ich würde eine Begrenzung auf z.B. eine maximale Zusatzgröße von 50 MB je ReAllocateMemory() einbauen. Damit hat man maximal 50 MB Speicher zuviel reserviert. Ich hab mal fix mit einer Excel-Tabelle die Anzahl der Verdopplungen bei einer Obergrenze von 50 MB geprüft: Ausgehend von 512 Byte Basisgröße wären demnach nur 57 ReAllocateMemory() nötig, um auf über 2 GB reservierten Speicher zu kommen.

Ich will niemandem vorschreiben, wie er sein Programm gestalten soll, nur ging mir dieser Gedanke mit der unbegrenzten Verdoppelung durch den Kopf.

Gruß

Re: DynamicMemory

Verfasst: 22.07.2011 13:27
von STARGÅTE
demnach nur 57 ReAllocateMemory() nötig
nur ? :lol: hast du schon mal ein ReAllocateMemory() im Bereich von mehreren 100 MB ausgeführt ?
Da brauch ein ReAllocateMemory() schon fast eine Sekunden (jenachdem wie viel Ram man noch frei hat)

Deine Theorie ist sicher richtig das man bei 2 GB + 1 Word nicht 4GB erstellen muss, aber das Beispiel ist völlig unrealistisch!

Erstens gehts hier um unbekannte großen (bei dir weißt du ja das du 2 GB + 1 Word brauchst, also reservierst du es einfach)
Und zweitens gehts hier um KBs nicht um GBs /:->

EDIT: Ich würde einfach vorschlagen, dass man selbst bei DYMNewMemory() angeben kann wie groß der Buffer gewählt werden soll, und dessen vergrößerungsfaktor:
DYMNewMemory(1024, 1) wäre dann immer 1024 mehr, egal wie groß der speicher ist
DYMNewMemory(200, 2) wäre dann bei erste mal 200, dann 400, dann 800, dann 1600

Re: DynamicMemory

Verfasst: 22.07.2011 13:33
von ullmann
OK, ich habe noch nie ein ReAllocateMemory ausgeführt. Wenn die Werte klein bleiben, braucht man natürlich keine Begrenzung.