Seite 1 von 2

Speicherleck bei Strings 3.94

Verfasst: 24.01.2006 19:32
von remi_meier
Ausgehend von diesem Thread:
http://forums.purebasic.com/german/view ... highlight=

Wer kein AllocateMemory() für Strukturen mit Stringfeldern benutzt, muss
nicht beunruhigt sein. Es geht also um Codes wie der folgende:

Code: Alles auswählen

Structure TestStruc 
   l.l 
   s.s 
   f.f
   s2.s 
EndStructure 

*pElement.TestStruc = AllocateMemory(SizeOf(TestStruc))
*pElement\s = "hallo"
*pElement\s2 = "welt"
FreeMemory(*pElement)
; Hier entsteht ein Speicherleck: \s und \s2 werden NICHT
; von PB automatisch freigegeben! Auch ein Zuweisen eines
; Leerstrings ("") hilft nicht viel.
PB stellt also direkt keine Möglichkeit zur Verfügung um diese Strings aus
dem Speicher zu entfernen! Wenn man nun den ASM-Output liest, findet
man jedoch eine Methode :) . Dazu habe ich 2 Prozeduren gemacht:

Code: Alles auswählen

Procedure FreeStructuredString1(ptrstruct, offset.l)
  Protected p.l
  p = AllocateMemory(8)
  PokeL(p, offset)
  PokeL(p + 4, -1)
  !PUSH dword[esp+8] ; Pointer auf 'p'-Bereich
  !PUSH dword [esp+4] ; ptrstruct
  !CALL _SYS_FreeStructureStrings@8
  FreeMemory(p)
EndProcedure 
und

Code: Alles auswählen

Procedure FreeStructuredString2(ptrstruct.l, ptroffsets.l) 
  !PUSH dword [esp+4] ; offsets der Strings
  !PUSH dword [esp+4] ; ptrstruct 
  !CALL _SYS_FreeStructureStrings@8
EndProcedure 
Zur Anwendung zwei Codebeispiele:

Code: Alles auswählen

Structure TestStruc 
   l.l 
   s.s 
   f.f
   s2.s 
EndStructure 

*pElement.TestStruc = AllocateMemory(SizeOf(TestStruc))
*pElement\s = "hallo"
*pElement\s2 = "welt"
; vor dem FreeMemory() noch die Strings freigeben.
; dazu muss die Funktion für jeden String einzeln aufgerufen
; werden:
FreeStructuredString1(*pElement, OffsetOf(TestStruc\s))
FreeStructuredString1(*pElement, OffsetOf(TestStruc\s2))
; nun sind die Strings nicht mehr benutzbar und nicht
; mehr im Speicher.
FreeMemory(*pElement)
Die Methode mit FreeStructuredString2() ist komplizierter, aber allgemeiner
oder doch auch wieder einfacher?

Code: Alles auswählen

Structure TestStruc 
   l.l 
   s.s 
   f.f
   s2.s 
EndStructure 

; Beliebig viele Offsets der Strings mit abschliessendem -1
; muss für jede Struktur gemacht werden!
DataSection
offTestStruc: 		; Label zum Zugriff
	Data.l OffsetOf(TestStruc\s), OffsetOf(TestStruc\s2), -1
; also etwa so:
; Data.l Offset1, Offset2, -1
; oder wie im Beispiel:
; Data.l 4, 12, -1
; dabei geht auch für grössere Strukturen z. B.
; Data.l Offset1, Offset2, Offset3, Offset4, ... , OffsetN, -1
EndDataSection

*pElement.TestStruc = AllocateMemory(SizeOf(TestStruc))
*pElement\s = "hallo"
*pElement\s2 = "welt"
; vor dem FreeMemory() noch die Strings freigeben.
; dazu muss die Funktion für die Struktur einmal aufgerufen
; werden. Dabei muss neben dem Pointer auf die Struktur, der
; Pointer zu unseren Offsets übergeben werden (?labelname)
FreeStructuredString2(*pElement, ?offTestStruc)
; nun sind die Strings nicht mehr benutzbar und nicht
; mehr im Speicher.
FreeMemory(*pElement)
Variante 2 kann man natürlich für beliebig viele Strukturen machen!

greetz
Remi

Verfasst: 24.01.2006 23:22
von helpy
Hi remi,

SUPER!

Noch eine Frage (ich selbst brauch es zwar nicht, aber vielleicht ist es ja relevant für andere).

Was passiert bei verschachtelten Strukturen?

Code: Alles auswählen

Structure st1
	s1.s
	a.l
	s2.s
	b.l
EndStructure

Structure st2
	test.st1
	y.l
	s.s
EndStructure

; AllocateMemory(SizeOf(st2))
Wie würde das wohl hier aussehen?

Verfasst: 24.01.2006 23:59
von NicTheQuick
Ich denke das geht dann so:

Code: Alles auswählen

DataSection
  offst2:
    Data.l OffsetOf(st2\test\s1), OffsetOf(st2\test\s2), OffsetOf(st2\s), -1
EndDataSection

Verfasst: 25.01.2006 00:19
von helpy
NicTheQuick hat geschrieben:Ich denke das geht dann so:

Code: Alles auswählen

DataSection
  offst2:
    Data.l OffsetOf(st2\test\s1), OffsetOf(st2\test\s2), OffsetOf(st2\s), -1
EndDataSection
Yep! Das sieht logisch aus! ... hätte wohl nur ein wenig mehr nachdenken müssen :-(

Verfasst: 25.01.2006 20:25
von remi_meier
Funktioniert hier nicht :?

Ausserdem geht es so nicht... Und ich bin auch gerade etwas zu ausgelaugt
um zu verstehen, was mir der ASM-Output sagen will:

Code: Alles auswählen

s_st1:
 dd 0
 dd 8
 dd 12
 dd 20
 dd -1
s_st2:
 dd -2, 1, 0, 24, s_st1
 dd 28
 dd -1
bei einer Struktur wie

Code: Alles auswählen

Structure st1 
   s1.s 
   a.l 
   s2.s 
   s3.s
   b.l 
   s4.s
EndStructure 

Structure st2 
   test.st1 
   y.l 
   s.s 
EndStructure
Das Problem ist die 24, die sich immer verändert wenn man an st1 was
ändert... Hab da jetzt grad keine Idee.
Sry.

Ich vermute, es würde auch so gehen (ungetestet und keine Garantie):

Code: Alles auswählen

DataSection
offsets:
Data.l OffsetOf(st2\test) + OffsetOf(st1\s1), OffsetOf(st2\test) + OffsetOf(st1\s2), OffsetOf(st2\test) + OffsetOf(st1\s3)
Data.l OffsetOf(st2\test) + OffsetOf(st1\s4), OffsetOf(st2\s), -1
EndDataSection
greetz
Remi

Verfasst: 25.01.2006 21:44
von PMV
Das Problem ist die 24, die sich immer verändert wenn man an st1 was
ändert... Hab da jetzt grad keine Idee.
Sry.
Ich hab zwar keine ahnung von ASM ... aber wenn ich die Speichergröße von st1 nehme dann kommt man doch auf 24. Sind ja 6 Elemente, mal 4 = 24 :D .

Oder verhält sich das anders?

MFG PMV

Verfasst: 25.01.2006 21:55
von remi_meier
Stimmt, lol :D
Hab mich da wohl verrechnet (glaubs mir einfach^^)

Dann könnte das wohl folgendermassen aussehen:

Code: Alles auswählen

Structure st1 
   s1.s 
   a.l 
   s2.s 
   s4.s 
EndStructure 

Structure st2 
   test.st1 
   y.l 
   s.s 
EndStructure


DataSection
offst1:
Data.l OffsetOf(st1\s1), OffsetOf(st1\s2), OffsetOf(st1\s4), -1
offst2:
Data.l -2, 1, 0, SizeOf(st1), ?offst1
Data.l OffsetOf(st2\s), -1
EndStructure
Was die 1 und die 0 sollen, weiss ich allerdings nicht... Ein Risiko ist also
da.

Und es könnte auch auf Linux laufen, einfach ausprobieren, hab keins und
weiss deshalb nicht, ob da was anders läuft. Die Chancen stehen aber gut.

greetz
Remi

Verfasst: 25.01.2006 22:16
von Deeem2031
Die StructureMap hab ich doch schonmal erklärt: http://forums.purebasic.com/german/view ... 49&start=0
Der Code ganz unten auf der 1. Seite dürfte alles erklären, mit der Ausnahme das ich damals nicht verschachtelte Strukturen beobachtet hab, aber das sollte ja nich so schwer sein. ;)

Verfasst: 25.01.2006 22:25
von remi_meier
Netter Code :)
Aber genau das ist ja das Problem (oder jetzt ev. auch nicht mehr). Also
die nicht verschachtelten Strukturen stehen ja schon im ersten Post, un-
sicherheit besteht nur bei verschachtelten Strukturen (obwohl das auch
durch einen kleinen Test geklärt werden könnte, wozu ich aber leider zu
faul bin).
Wenn du da Informationen hast, sind wir dir dankbar (also v. a. die 0 und
die 1 aus dem Post darüber)!

greetz
Remi

Verfasst: 25.01.2006 22:31
von Deeem2031
Hm, dann hab mir den Thread wohl doch zu ungenau durchgelesen ;)
Aber ich versuch grad Fred zu erreichen, wenn ichs schaff frag ich ihn gleich ma desswegen.