home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / cebit_91 / tricks / realloc2.doc < prev    next >
Encoding:
Text File  |  1991-03-07  |  4.9 KB  |  111 lines

  1. Neuigkeiten für Turbo Pascal 6.0:
  2. "FreePtr" umschifft, und "realloc" funktioniert doch! (Trickkiste 6'91)
  3.  
  4. Die Unit "Realloc" die Sie ebenfalls auf dieser Diskette finden,
  5. implementiert für Turbo Pascal 5.x die
  6. Funktion »ChangeMem«, mit deren Hilfe sich die Größe des
  7. Speicherbereichs, den eine Zeigervariable auf dem Heap
  8. belegt, während der Programmlaufzeit verändern läßt. Eine
  9. sehr nützliche Sache, wenn man viel mit dynamischen Daten
  10. arbeitet.
  11.  
  12. Wenn Sie jedoch versuchen, diese Unit auch unter der neuen
  13. Turbo-Pascal-Version 6.0 einzusetzen, erleben Sie eine
  14. Enttäuschung: Der Compiler weigert sich glattweg, den
  15. Quelltext zu verarbeiten.
  16.  
  17. Was ist passiert? Daß mit Turbo-Pascal 6.0 etliche Neuerun-
  18. gen eingeführt wurden, ist nicht zu übersehen. Vor allem
  19. wären da die neue Entwicklungsumgebung, das Turbo-Vision-
  20. Paket sowie der integrierte Assembler zu nennen. Aber die
  21. einschneidendste interne Veränderung hat Borland am Heap-
  22. Manager der Laufzeitbibliothek vorgenommen -- und dies ist
  23. auch der Grund, warum alle Programme, die aktiv in die Heap-
  24. Verwaltung eingreifen, unter der Version 6.0 nicht mehr lau-
  25. fen. Gerd Cebulla hat sich die neuen Speizalitäten einmal
  26. angesehen.
  27.  
  28. Die Prozeduren "New"/"Dispose", "GetMem"/"FreeMem" sowie
  29. "Mark"/"Release" gibt es nach wie vor. Auch die Systemvaria-
  30. blen "HeapOrg" und "HeapPtr" sind noch vorhanden: "HeapOrg"
  31. ist ein Zeiger auf den Beginn des Heap und bleibt während
  32. des gesamten Programmlaufs konstant, "HeapPtr" dagegen ent-
  33. hält die Startadresse des freien Heap. Neu hinzugekommen ist
  34. die Variable "HeapEnd", die auf das Ende des Heap und damit
  35. auch auf das Ende des Programmspeichers zeigt.
  36.  
  37. Die Fragmentliste jedoch, in der die Turbo-Pascal-Versionen
  38. bis 5.5 die freien Bereiche des Heap festhielten, existiert
  39. nicht mehr! Oder präziser ausgedrückt: Die Laufzeitbiblio-
  40. thek von Turbo-Pascal 6.0 verwaltet die "Löcher" im Heap
  41. nicht mehr in Form einer Tabelle am oberen Ende des Spei-
  42. chers, sondern als einfach verkettete dynamische Liste. Je-
  43. desmal, wenn Sie mit "Dispose" oder "FreeMem" eine dynami-
  44. sche Variable freigeben, werden die ersten acht Byte des so
  45. entstandenen Lochs mit einem Record belegt, den man wie
  46. folgt definieren könnte:
  47.  
  48. TYPE
  49.   FreePtr = ^FreeRec;
  50.   FreeRec = RECORD
  51.               Next : FreePtr;
  52.               Size : Pointer;
  53.             END;
  54.  
  55. Das Feld "Next" ist dabei ein Zeiger auf das nächste Loch;
  56. wenn sein Wert mit dem von "HeapPtr" identisch ist, handelt
  57. es sich um das letzte Glied der Liste. Das Feld "Size" ent-
  58. hält die Größe des Lochs, allerdings in etwas ungewöhnlicher
  59. Form: nämlich als eine Art normalisierter Zeiger. Das bedeu-
  60. tet, im höherwertigen Word von "Size" ist die Anzahl der
  61. Paragraphen (16-Byte-Einheiten) verzeichnet, und im nieder-
  62. wertigen Word stehen die restlichen Byte, die bei der Divi-
  63. sion durch 16 übrigbleiben.
  64.  
  65. Die Adresse des allerersten Lochs im Heap entnehmen Sie der
  66. Systemvariablen "FreeList"; wenn "FreeList" gleich "HeapPtr"
  67. ist, enthält der Heap keine Löcher. Bleibt nur noch zu klä-
  68. ren, wozu die Zeigervariable "FreeZero" dient, die ebenfalls
  69. in der Unit "System" definiert ist und beim Programmstart
  70. auf den Wert »nil« initialisiert wird. Die Handbücher und
  71. die integrierte Hilfestellung schweigen sich dazu aus, und
  72. in Borlands Dokumentationsdatei "SYSTEM.INT" findet sich nur
  73. die nebulöse Anmerkung "must be zero".
  74.  
  75. Des Rätsels Lösung ergibt sich erst nach einigem Nachdenken.
  76. Da "FreeZero" gleich hinter "FreeList" deklariert wird, sind
  77. die beiden Variablen auch im Datensegment an direkt aufein-
  78. anderfolgenden Adressen gespeichert. Somit läßt sich das
  79. Variablenpaar "FreeList"/"FreeZero" auch als Record vom Typ
  80. "FreeRec" behandeln, wobei der Platz des Feldes "Size" durch
  81. "FreeZero" eingenommen wird und sein Wert in diesem speziel-
  82. len Fall natürlich immer Null betragen muß! Dieses Verfahren
  83. fällt zwar eindeutig in die Kategorie "dirty tricks" - aber
  84. es funktioniert und spart nebenbei eine ganze Menge Verwal-
  85. tungsaufwand.
  86.  
  87. Soviel zu den Grundlagen. Die Unit "ReAlloc2" wurde für die
  88. Turbo-Pascal-Version 6.0 zwar gründlich überarbeitet, der
  89. Aufruf der Funktion "ChangeMem" ist aber gleichgeblieben:
  90.  
  91. PNew := ChangeMem(P, OldSize, NewSize);
  92.  
  93. Der Parameter "P" enthält die Adresse der dynamischen Varia-
  94. ble, "OldSize" ihre derzeitige Größe und "NewSize" die ge-
  95. wünschte neue Größe. Das Funktionsergebnis ist ein Zeiger
  96. auf die neue Adresse der dynamischen Variable. Falls auf dem
  97. Heap nicht mehr genug Platz verfügbar ist, wird der Wert
  98. "NIL" zurückgegeben - vorausgesetzt daß Sie die Systemvaria-
  99. ble "HeapError" auf eine eigene Fehlerroutine gesetzt haben,
  100. die im einfachsten Fall wie folgt aussehen könnte:
  101.  
  102. FUNCTION HeapFunc(Size : WORD) : INTEGER; FAR;
  103. BEGIN
  104.   HeapFunc := 1;
  105. END;
  106.  
  107. Um andere Anwendungen an die neueste Version von Turbo
  108. Pascal anzupassen, wäre natürlich eine Standard-Unit
  109. willkommen. Wir sind bereits am Planen, aber vielleicht
  110. fällt Ihnen ja schon jetzt etwas ein...
  111.