amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > Garbage Collections umgehen [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- 2 [ - Beitrag schreiben - ]

06.02.2007, 10:05 Uhr

MaikG
Posts: 5172
Nutzer
Ich hab ein Programm das mit etwa 16000 Strings arbeitet.
Darin eine Funktion die eine Gui mit Buttons und Listviews erstellt.
Rufe ich die Funktion mehrmals auf und schliesse ich die wieder
werden die Listviews zerstört und CGX/Gadtools/Intuition machen
Lesezugriffe auf Speicherbereiche im unteren bereich.

Ich benutze eine Heap größe von 1500, es tritt jedes 14. mal auf.
Nehme ich z.B. 16384 tritt das Problem erst nach 129 mal auf.

In Basic werden in Taglists zeiger auf Strings verwendet, auch in
der Sub die einträge zu den Listviews hinzufügt.

Was könnte ich nun machen um das Problem zu beseitigen?
Muss ich die Strings etwa in einem Speicherbereich bringen
den ich mit AllocMem geholt habe? Dann könnten die Strings ja
nicht verschoben werden, ist allerdings umständlich.

[ - Antworten - Zitieren - Direktlink - ]

06.02.2007, 10:45 Uhr

Holger
Posts: 8116
Nutzer
Es reicht vermutlich aus, wenn Du mit DIM$(...) ein Array anlegst, und jeden String in einem der Feldeinträge ablegst. Dann gibt es eine Referenz auf den String und er wird auch nicht aus dem Speicher geworfen.

Dazu musst Du allerdings jedem String eine eindeutige integer-id zuordnen, damit sie alle sauber in dem Array abgelegt werden können. Hat aber den Vorteil, dass Du später leichter eine Lokalisierung einbauen könntest, weil die String in den Katalogen auch via integer-id adressiert werden.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

06.02.2007, 14:26 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Ich habe dein Problem nicht ganz verstanden.
Was meinst du mit "Lesezugriffe auf Speicherbereiche im unteren bereich" ?

Du solltest auf jeden Fall sicherstellen, dass die Lebensdauer der Strings so lange ist wie intuition sie benutzt.
Viele Befehle machen keine Kopie des strings.
Wenn du also eine Lokale Variable bentzt, die am ende der Funktion freigegeben wird, kann es zu trash kommen.

Auch der umgekehrte Fall ist Problematisch, wenn eine OS Funktion den String freigibt. Dann darfst du keine Basic String nehmen, weil Basic ja nicht wissen kann das die OS Funktion den String bereits freigegeben hat. In dem Fall musst du das mit allocmem oder allocvec allocieren, je nachdem was im RKM steht.

Mit Garbadge Collection hat das aber alles nichts zu tun.

Im Zeifelsfall Amiblitz benutzen ;-)

--
Thilo Köhler, Author von:
HD-Rec, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, TKUnpacker
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

06.02.2007, 14:45 Uhr

MaikG
Posts: 5172
Nutzer
>Es reicht vermutlich aus, wenn Du mit DIM$(...) ein Array anlegst,
>und jeden String in einem der Feldeinträge ablegst.

Also die meisten sind in einer Variable, ich hab es aber auch
mit den anderen probiert, es ging trotzdem nicht.


>Ich habe dein Problem nicht ganz verstanden.

Naja, also die Listviews sind Leer(nach dem 14.mal), beim 4. Eintrag
in jedem Listview geht dieser viel weiter nach Links also Negativ vom
Listview beginn weg.

>Was meinst du mit "Lesezugriffe auf Speicherbereiche im unteren
>bereich" ?

Byte Read from 21
Word Read from 06
Word 1A
Word 14
Word 14
Word E
Word 14
Word 6

Ist nur ein Auszug den ich aufgeschrieben habe.

>Du solltest auf jeden Fall sicherstellen, dass die Lebensdauer der
>Strings so lange ist wie intuition sie benutzt.

Also in den Beispielen wird das ja auch nicht gemacht.

>Viele Befehle machen keine Kopie des strings.

Welche? Welche vom Listview oder Fenstertitel vielleicht?

>Wenn du also eine Lokale Variable bentzt, die am ende der Funktion
>freigegeben wird, kann es zu trash kommen.

Ich hab zuletzt ale Variablen als Lokal definiert, damit diese
beim Funktionsaufruf alle gelöscht werden.
Aber die Funktion ist praktische ein eigenständiges Programm
also alles was geöffnet wurde ist dann wieder zu.

code:
SUB NewList(BYVAL list&)
	POKEL list& + lh_Head%, list& + lh_Tail%
	POKEL list& + lh_Tail%, 0
	POKEL list& + lh_TailPred%, list& + lh_Head%
END SUB

SUB AddName(Nodes&(),listh&,TmpVar$(0), BYVAL Anzahl%, Nodes%)
 LOCAL namenode&
	namenode&=AllocMem&(node_sizeof%,MEMF_CLEAR&)
	IF namenode&=0 THEN ERROR 7	' out of memory
        Nodes&(Anzahl%-Nodes%)=namenode&:INCR Nodes%
	POKEL namenode&+ln_Name%, SADD(TmpVar$(0))
	AddHead listh&,namenode&
END SUB

rem Aufrufsprinzip des Subs
AddName Nodes&(), listviewlist&, TmpVar$(), Einträge%, Nodes%


SUB FreeListGadget(BYVAL listhead&)
STATIC worknode&,nextnode&
worknode&=PEEKL(ListHead&+lh_head%)
DO
	nextnode&=PEEKL(worknode&+ln_Succ%)
	IF nextnode&=0 THEN EXIT LOOP
	FreeMem worknode&,node_sizeof%
	worknode&=nextnode&
LOOP
END SUB

 TAGLIST VARPTR(temptag&(0)), _
  WA_Title&,     "         Ein Fehler ist Aufgetreten", _
  WA_AutoAdjust&,  TRUE&, _
  WA_InnerWidth&,  455&, _
  WA_InnerHeight&, 102&, _
  WA_DragBar&,    TRUE&,      WA_DepthGadget&,   TRUE&, _
  WA_Activate&,   TRUE&,      WA_CloseGadget&,   TRUE&, _
  WA_SizeGadget&, FALSE&,     WA_SmartRefresh&,  TRUE&, _
  WA_IDCMP&, IDCMP_CLOSEWINDOW&+IDCMP_REFRESHWINDOW&+ _
  +IDCMP_MOUSEBUTTONS&, _
  WA_PubScreen&, mysc&, _
 TAG_END&

 mywinFR& = OpenWindowTagList&(NULL&,VARPTR(temptag&(0)))



Nehme ich AddName raus, also Listviews leer tritt der Fehler
nicht auf. Ein beispiel für ein Fenster ist unten.

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 10:27 Uhr

thomas
Posts: 7717
Nutzer
@MaikG:
Zitat:
code:
POKEL namenode&+ln_Name%, SADD(TmpVar$(0))

AddName Nodes&(), listviewlist&, TmpVar$(), Einträge%, Nodes%




Deine Namen kommen offenbar aus TmpVar$. Aber was das ist, wo es herkommt und wie lange es lebt, darüber schreibst du gar nichts.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 11:31 Uhr

MaikG
Posts: 5172
Nutzer
>Deine Namen kommen offenbar aus TmpVar$. Aber was das ist, wo es herkommt und wie lange es lebt, darüber schreibst du gar nichts.

Ja, ich hab ebend noch experimentiert.
Die größe eines Nodes ist 20 Bytes, darin passt ja nun nie und nimmer
ein String mit einer länge von ca. 25 Zeichen und dazu noch die
Zeiger.

Das MaxonBasic Beispiel war ja:

code:
listhead&=AllocMem&(list_sizeof,MEMF_CLEAR&)
NewList listhead&
FOR i=15 TO 0 STEP -1
	AddName	listhead&,"line"+STR$(i)
NEXT i


also ein Temporärer String, ich ging davon aus das dieser nach
dem 1. mal weg ist und von daher dachte ich nicht das ich diesen
erhalten müsste.
Das Beispiel konnte ich auch sofort abstürzen lassen indem ich nach diesem
Code noch diverse Strings erstellte/veränderte und danach
CreateGadgetA& aufgerufen habe.
Bei meinem Programm wird ja mit 100x soviel einträgen gearbeitet.
Das erhöhen des Heaps erhöhte also nur den Puffer für Temporäre,
Strings die viel länger dableiben als ich dachte.

Also brauche ich ein Array welches dableibt bis das Listview
weg ist richtig?

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 12:00 Uhr

thomas
Posts: 7717
Nutzer
Zitat:
Also brauche ich ein Array welches dableibt bis das Listview
weg ist richtig?


Das war ja genau das, was Holger dir vorgeschlagen hat.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 12:12 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von MaikG:
>Deine Namen kommen offenbar aus TmpVar$. Aber was das ist, wo es herkommt und wie lange es lebt, darüber schreibst du gar nichts.

Ja, ich hab ebend noch experimentiert.
Die größe eines Nodes ist 20 Bytes, darin passt ja nun nie und nimmer
ein String mit einer länge von ca. 25 Zeichen und dazu noch die
Zeiger.


Schau Dir nochmal GANZ genau an, was ein Node ist und wie der funktioniert. Der String, den Du dort unterbringen willst, erscheint nicht selbst im Node, sondern "nur" ein Zeiger auf diesen.

Mit der Größe der Node-Struktur hat Dein Problem rein gar nichts zu tun. Dir gehen die dort in Form eines Zeigers abgelegten Strings flöten, welche aus dem TmpVar$-Array stammen.

Die Frage von thomas zielte auch darauf ab, wie lange TmpVar$ denn nun "überlebt". Darüber sagst Du immer noch nichts.

Zitat:
Das MaxonBasic Beispiel war ja:

code:
listhead&=AllocMem&(list_sizeof,MEMF_CLEAR&)
NewList listhead&
FOR i=15 TO 0 STEP -1
	AddName	listhead&,"line"+STR$(i)
NEXT i


also ein Temporärer String, ich ging davon aus das dieser nach
dem 1. mal weg ist und von daher dachte ich nicht das ich diesen
erhalten müsste.


Soweit ich weiß, ist in BASIC eine String-Konstante nie temporär, "line" bliebe also bis zum Ende des Programms erhalten. Mit dem STR$-Teil sieht es etwas anders aus, dabei kommt eine temporäre String-Variable "line15" (z.B.) heraus, die abhängig vom Interpreter/Compiler bis zur nächste GC auf dem Heap liegen bleibt oder sofort wieder verschwindet.

Zitat:
Das Beispiel konnte ich auch sofort abstürzen lassen indem ich nach diesem
Code noch diverse Strings erstellte/veränderte und danach
CreateGadgetA& aufgerufen habe.


Wer weiß, was dabei sonst noch alles schiefläuft...

Zitat:
Bei meinem Programm wird ja mit 100x soviel einträgen gearbeitet.
Das erhöhen des Heaps erhöhte also nur den Puffer für Temporäre,
Strings die viel länger dableiben als ich dachte.


Was dachtest Du denn da genau? In BASIC ist es meist so, daß bei Variablen mit Block-Scope (sprich: temporär innerhalb der aktuellen Funktion gültig) diese nach Verlassen des Blocks nicht mehr ansprechbar sind, aber trotzdem im Variablen-Bereich des Interpreter-/Runtime-Heap bis zur nächsten Garbage-Collection erhalten bleiben.

Da Du dem Node einen Zeiger mitgibst, bleibt der betreffende String noch eine Weile erhalten, auch wenn er temporär erzeugt wurde. Wie lange das genau ist, hängt vom Zeitpunkt ab, an dem der Interpreter/Compiler die GC auslöst.

Zitat:
Also brauche ich ein Array welches dableibt bis das Listview
weg ist richtig?


Genau. Woher soll sich das ListView sonst die Daten holen, wenn z.B. ein Refresh angesagt ist? Die temporären Daten sind ja u.U. schon längst wieder futsch.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 13:10 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Also brauche ich ein Array welches dableibt bis das Listview
weg ist richtig?

Oder Du änderst die AddName() Routine so, dass sie für die ListNode noch Stringlänge+1 byte mehr belegt, kopierst den String dort hinter die ListNode-Struktur und setzt den Zeiger nicht auf den Basic-String, sondern auf die Kopie.

In etwa so (aus Zeitmangel ungetestet)
code:
SUB AddName(Nodes&(),listh&,Name$, BYVAL Anzahl%, Nodes%)
  LOCAL namenode&
  namenode&=AllocVec&(node_sizeof% + LEN(Name$)+1,MEMF_CLEAR&)
  IF namenode&=0 THEN ERROR 7	' out of memory
  Nodes&(Anzahl%-Nodes%)=namenode&:INCR Nodes%
  POKE$ namenode&+node_sizeof%, Name$
  POKEL namenode&+ln_Name%, namenode&+node_sizeof%
  AddHead listh&,namenode&
END SUB

Dann änderst Du noch die Stelle, wo FreeMem aufgerufen wird, in FreeVec, und die Strings werden zum richtigen Zeitpunkt freigegeben.
Das ist einfacher als jede andere Verrenkung...

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ Dieser Beitrag wurde von Holger am 07.02.2007 um 13:10 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 14:01 Uhr

Der_Wanderer
Posts: 1229
Nutzer
code:
AddName	listhead&,"line"+STR$(i)

Das kannst du schmal komplett vergessen.
Der String existiert maximal für die Zeit des Funktionsaufrufes von AddName, und wird danach sofort verworfen.

Schau mal in RKM was AddName genau will, und was es mit dem String macht, also eine Kopie, gar nichts oder sogar selbst frei geben.
Dementsprechend musst du einen Pointer übergeben, der die Bedingungen erfüllt.

--
Thilo Köhler, Author von:
HD-Rec, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, TKUnpacker
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 14:44 Uhr

thomas
Posts: 7717
Nutzer
@Der_Wanderer:
Zitat:
Schau mal in RKM was AddName genau will

AddName gibt es nicht, das ist eine selbstgeschriebene Unterroutine. Siehe o.a. Codeschnipsel.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 14:48 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Achso, dann ist es klar.
TmpVar überlebt das verlassen der Subroutine AddName nicht, damit ist der Pointer auf den String ungültig.
Kein Wunder dass es crashed.


--
Thilo Köhler, Author von:
HD-Rec, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, TKUnpacker
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 14:59 Uhr

MaikG
Posts: 5172
Nutzer
>Die Frage von thomas zielte auch darauf ab, wie lange TmpVar$ denn
>nun "überlebt". Darüber sagst Du immer noch nichts.

Alle Temporären Strings überleben bis der Heap voll ist,
oder eine Garbage Collection stattfindet.


>Wer weiß, was dabei sonst noch alles schiefläuft...

Jede menge, das Listview war eines der Probleme, als ich
die Einträge in einem AllocMem bereich hatte waren die
einträge zwar nicht mehr Links über das LV hinaus, aber trotzdem
Leer.
Der String "topaz.font" muss auch überleben, also diesen auch
in einem AllocMem bereich, so geht es.
Allerdings ist jetzt der Fenstertitel zerstört, also muss
der Fenstertitelstring auch in einem AllocMem bereich.
Achso und ein String Array geht auch drauf bei einer GBC, wohl
weil MBasic Strings beliebig lang sein können.

Das ist irgendwie super umständlich.

Im NDK steht zumindest das ich eine Windowstruktur löschen
kann, nachdem das fenster offen ist. Vom String ist nicht die
Rede.

Ich will ja nicht wissen welche von meinen Programmen noch
abstürzen können wenn man diese lang genug "ärgert".
Und nichts davon in den beispielen, im Buch steht man
kann vorher überprüfen ob genug Heap für die Taglist da
ist und dann wohl eine GBC vorher selbst auslösen - aber
so werden alle vorherigen WindowTaglist - Strings zerstört.


>Was dachtest Du denn da genau?

entweder das der Node den String beinhaltet oder das LV sich
die Strings selbst Kopiert.


>Oder Du änderst die AddName() Routine so, dass sie für die ListNode
>noch Stringlänge+1 byte mehr belegt, kopierst den String dort hinter
>die ListNode-Struktur und setzt den Zeiger nicht auf den Basic-String,
>sondern auf die Kopie.

Cool, das scheint viel besser als meine Lösung.

POKE$ gibts allerdings nicht da muss
man

copymem SADD(Name$), namenode+node_sizeof%, LEN(Name$)

tun.


>Schau mal in RKM was AddName genau will, und was es mit dem String
>macht, also eine Kopie, gar nichts oder sogar selbst frei geben.
>Dementsprechend musst du einen Pointer übergeben, der die Bedingungen erfüllt.

AddName ist eine Basic Sub, AddHead ist dann die eigentliche exec Funktion.


[ Dieser Beitrag wurde von MaikG am 07.02.2007 um 15:00 Uhr geändert. ]

[ Dieser Beitrag wurde von MaikG am 07.02.2007 um 15:02 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 15:57 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Also darauf zu hoffen, dass ein Localer String nach dem Verlassen der Subroutine noch gültig ist, weil genug Heap da ist, damit Basic ihn nicht überschreibt ist ziemlich verwegen.

Das ist ungefähr so, als wenn du eine Datei löschst, den Papierkorb leerst und dein Program die Daten trotzdem noch via RAW access benutzt, in der Hoffnung dass die Platte gross genug ist, dass die Datei noch physikalisch da ist solange dein Program läuft!

Für sowas legst du besser globale Variablen an, oder wenn schon lokal, dann stelle zumindest sicher dass ihre Lebensdauer länger ist als das Listview bzw. Fenster exisitiert.
Das hat auch nichts mit Garbadge Collection zu tun, hat MBasic sowas überhaupt ?
Alles andere ist super Pfusch und crashed früher oder später.
--
Thilo Köhler, Author von:
HD-Rec, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, TKUnpacker
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 16:16 Uhr

MaikG
Posts: 5172
Nutzer
>Für sowas legst du besser globale Variablen an, oder wenn schon lokal,
>dann stelle zumindest sicher dass ihre Lebensdauer länger ist als
>das Listview bzw. Fenster exisitiert.
>Das hat auch nichts mit Garbadge Collection zu tun, hat MBasic sowas überhaupt ?
>Alles andere ist super Pfusch und crashed früher oder später.

Es spielt keine Rolle ob ein String Lokal, Static oder Global ist
MaxonBasic ändert ALLE Pointer von Strings bei einer Garbage Collection.

Das Listview wird erst beim Ende der Function geschlossen und offizell
werden auch dann erst die Strings gelöscht.

Ich könnte natürlich einen 4 Stelligen String in eine Long Integer
geben aber für einen 40 Stelligen String ist das noch umständlicher
als AllocMem.

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 16:21 Uhr

Der_Wanderer
Posts: 1229
Nutzer
> Es spielt keine Rolle ob ein String Lokal, Static oder Global ist
> MaxonBasic ändert ALLE Pointer von Strings bei einer Garbage
> Collection.
Achso. Dann hast du ja gleich zwei Probleme in deinem obigen Source:
1. dass der String nicht mehr gültig ist
2. dass auch wenn du ihn gültig halten würdest, er die bei einer Garbadge Collection "unter den Füssen" weggezogen wird.

Da hilft nur string manuell anlegen mit Allocmem, oder auch gleich an die Node anhängen, wenn die schon allociert wird.

--
Thilo Köhler, Author von:
HD-Rec, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, TKUnpacker
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 17:29 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von MaikG:
>Für sowas legst du besser globale Variablen an, oder wenn schon lokal,
>dann stelle zumindest sicher dass ihre Lebensdauer länger ist als
>das Listview bzw. Fenster exisitiert.
>Das hat auch nichts mit Garbadge Collection zu tun, hat MBasic sowas überhaupt ?
>Alles andere ist super Pfusch und crashed früher oder später.

Es spielt keine Rolle ob ein String Lokal, Static oder Global ist
MaxonBasic ändert ALLE Pointer von Strings bei einer Garbage Collection.


Ich kann mich ganz dunkel daran erinnern, daß man MB mitteilen konnte, in welcher Form die GC abgewickelt wird.

Normal werden bei der GC auch die Strings "neu sortiert", soll heißen, die Fragmentierung des Heaps wird beseitigt. Das scheint bei Dir der Fall zu sein.

Soweit ich mich erinnere, konnte man MB aber von der Defragmentierung des String-Speichers abhalten, aber frag mich nicht, welche Option dafür zuständig ist. Blick ins Handbuch dazu könnte helfen.

Andererseits ist Holgers Lösung geradezu brilliant, um weitere mögliche Probleme mit der GC zu verhindern.

Mach das besser so, wie Holger vorgeschlagen hat, dann gibts keine Sorgen in der Hinsicht.

Und für das nächste Mal weißt Du dann, wie man solche Problemchen umgehen kann :D

Zitat:
Ich könnte natürlich einen 4 Stelligen String in eine Long Integer
geben aber für einen 40 Stelligen String ist das noch umständlicher
als AllocMem.


Es ist noch die Frage, ob Dir das wirklich weiterhelfen würde. Mit ein bißchen Pech betreibt MB Wiederverwendung mit dem Platz der jeweiligen LONGs, dann geht das Theater von vorn los.

Das Schlaueste ist es wohl wirklich, das Ganze in C-Manier zu handhaben, also die Strings via AllocVec() von Hand zu allozieren und an die Node-Struktur anzuhängen.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 18:00 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von Der_Wanderer:
Das hat auch nichts mit Garbadge Collection zu tun, hat MBasic sowas überhaupt ?


Ja, hat es. Das hat jeder echte BASIC-Interpreter/Compiler.

AmiBlitz fällt da aus der Reihe, im Prinzip ist es kein echter BASIC-Compiler sondern eine Mischung aus C-Compiler und BASIC-Schlüsselworten und -Konstrukten. Kann sogar gut sein, daß AB auch eine Art Garbage Collector einsetzt, so weit habe ich den Compiler nicht durchblickt.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 18:07 Uhr

MaikG
Posts: 5172
Nutzer
>Soweit ich mich erinnere, konnte man MB aber von der
>Defragmentierung des String-Speichers abhalten, aber frag mich
>nicht, welche Option dafür zuständig ist. Blick ins Handbuch dazu
>könnte helfen.

Ich hab schon Handbuch und Docs abgesucht, es gibt zwar einen
Heap der nicht Dynamisch ist, da passiert aber das selbe.

>Andererseits ist Holgers Lösung geradezu brilliant, um weitere
>mögliche Probleme mit der GC zu verhindern.

Ja, hab das bereits Integriert, Funktioniert.
Obwohl ich mir nicht ganz sicher bin ob

POKEL namenode&+ln_Name%, namenode&+node_sizeof%

nicht

POKEL namenode&+ln_Name%, namenode&+node_sizeof%+1

heissen müsste.

>Das Schlaueste ist es wohl wirklich, das Ganze in C-Manier zu
>handhaben, also die Strings via AllocVec() von Hand zu allozieren
>und an die Node-Struktur anzuhängen.

Ja, das mit dem Listview ist ja nicht das schlimmste sowas muss ich
jetzt bei jedem Fenster machen...

Aber in C haben doch Strings eine feste länge und müssten deshalb
doch gar nicht "defragmentiert" werden oder?

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 18:43 Uhr

Der_Wanderer
Posts: 1229
Nutzer
Amiblitz hat keine Gargadge Collection.
String Operationen werden im String Buffer durchgeführt und der String am Ende in einem Pool abgelegt, der dynamisch ist.

D.h. man kann beliebig viele Strings haben. Nur die Maximale Länge ist durch den Stringbuffer vorgegeben, den kann man aber einstellen wie man will, und kostet ja nicht viel, z.B. 64K.

Man kann auch einen festen Stringbuffer einer Variablen zuweisen, um in bestimmen Situationen neu-allocierungen zu verindern. Das wäre dann so wie in C wenn man "char mystring[4096];" macht.

Aber das Problem scheint ja nu gelöst zu sein.

BTW, KEINE 1 dazuaddieren. Wenn du sizeof dazuaddierst, steht der Pointer ja auf dem nächsten Byte, was nach der Struct kommt.


--
Thilo Köhler, Author von:
HD-Rec, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, TKUnpacker
Homepage: http://www.hd-rec.de


[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 19:40 Uhr

Ralf27
Posts: 2779
Nutzer
Ja, das ist so ne Sache bei MB. Da hab ich mich auch als drüber aufgeregt. Vorallem bei Fenstertitel kann man dann die Aufräumaktion des Compilers sehn. Und dabei dachte ich auch immer, das z.b. direkt angegebene Strings im Quellcode fest wären. Also z.b. geht folgendes in die Hose:
code:
TAGLIST tagsl&,_
 WA_IDCMP&,IDCMP_CLOSEWINDOW&,_
 WA_Flags&,WFLG_CLOSEGADGET&+_
           WFLG_ACTIVATE&+_
           WFLG_SIZEGADGET&+_
           WFLG_DEPTHGADGET&+_
           WFLG_DRAGBAR&+_
           WFLG_SIMPLE_REFRESH&,_
 WA_MinHeight&,50,_
 WA_MinWidth&,100,_
 WA_Title&,"Netzwerkfenster",_
 TAG_END&
 con_win&=OpenWindowTagList&(0,tagsl&)


Deswegen hatte ich mal ne Funktion für Strings geschrieben, die unabhängig von MB gehaltet werden müssen:
code:
REM Die folgende Funktion brauch ich nur, weil sonst MaxonBasic mir die
REM Namen in den Fenstern versaut, wenn er wiedermal einfach die variablen
REM aufräumt
FUNCTION AllocName&(c$,BYVAL n)STATIC
 SHARED AllocN&()
 IF AllocN&(n)THEN FreeMem AllocN&(n),PEEKW(AllocN&(n)):AllocN&(n)=0
 a$=c$+CHR$(0)
 a&=LEN(a$)+2
 b&=AllocMem&(a&,MEMF_PUBLIC&)
 IF b& THEN
  AllocN&(n)=b&
  POKEW b&,a&
  CopyMem SADD(a$),b&+2,LEN(a$)
 END IF
 AllocName&=b&+2
END FUNCTION

Wobei c$ der String ist und n eine im Quellcode fortlaufende Zahl. Am Programmende müssen dann natürlich alle Speicherbereiche wieder freigegeben werden. Die Längen der Speicherbereiche steht dann immer an erster Stelle des Speicherbereichs als Word. Also einfach alles durchnummerieren, am Anfang ein Feld Namens AllocN& mit der Anzahl der Strings anlegen und gut ist.

Also einfach denn Code da oben wie folgt verändern:
code:
...
 WA_Title&,AllocName&("Netzwerkfenster",0),_
...


Der ganze Aufwand lohnt sich natürlich nur, wenn es einige Strings im Programm gibt, die gesichert werden müssen.

Kurze Anmerkung:
Ich hab jedem String eine feste Nummer gegeben, damit bei Programmablauf auch wieder Strings freigegeben werden, die nicht mehr benötigt wird. Das geht dann in der Funktion automatisch.

EDIT:
Ok, wenn kein Speicher mehr da ist, dann fehlt der Funktion die nötige Routine um es zu melden. Aber wenn wirklich mal 10 oder 15 Bytes Arbeitsspeicher nicht mehr frei sein sollten, dann ist was in die Hose gegangen. In meinem Fall benutze ich die Routine halt vorallem für kurze String wie Fensternamen, etc.
--
http://www.alternativercomputerclub.de.vu

[ Dieser Beitrag wurde von Ralf27 am 07.02.2007 um 19:44 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 22:04 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von MaikG:
>Soweit ich mich erinnere, konnte man MB aber von der
>Defragmentierung des String-Speichers abhalten, aber frag mich
>nicht, welche Option dafür zuständig ist. Blick ins Handbuch dazu
>könnte helfen.

Ich hab schon Handbuch und Docs abgesucht, es gibt zwar einen
Heap der nicht Dynamisch ist, da passiert aber das selbe.


Ok, dann wissen wir schon mal, daß man die GC in MB nicht weiter steuern kann. Der nicht-dynamische Heap macht übrigens die Garbage Collection gerade notwendig ;)

Zitat:
>Andererseits ist Holgers Lösung geradezu brilliant, um weitere
>mögliche Probleme mit der GC zu verhindern.

Ja, hab das bereits Integriert, Funktioniert.
Obwohl ich mir nicht ganz sicher bin ob

POKEL namenode&+ln_Name%, namenode&+node_sizeof%

nicht

POKEL namenode&+ln_Name%, namenode&+node_sizeof%+1

heissen müsste.


Wie Der_Wanderer schon bemerkte: Nein, muß es nicht.

Zitat:
>Das Schlaueste ist es wohl wirklich, das Ganze in C-Manier zu
>handhaben, also die Strings via AllocVec() von Hand zu allozieren
>und an die Node-Struktur anzuhängen.

Ja, das mit dem Listview ist ja nicht das schlimmste sowas muss ich
jetzt bei jedem Fenster machen...


Halb so wild. Ralphs Lösung dazu ist schon ganz i.O. und gut zu handhaben. Im Prinzip machst Du damit aus der statischen String-Verwaltung von BASIC eine mehr oder weniger dynamische auf OS-Basis alá C. Allozieren von Speicher für einen String, so wie es in C der Compiler für einen erledigt.

Der arbeitet meist auch mit AllocVec() für diese Zwecke (sofern er den String nicht auf dem Stack ablegt, weil temporär).

Zitat:
Aber in C haben doch Strings eine feste länge und müssten deshalb
doch gar nicht "defragmentiert" werden oder?


Die Strings selbst nicht, nein. Aber stell Dir doch mal vor, was mit dem Hauptspeicher passiert, wenn Du den bis zum Bersten mit Strings vollstopfst und dann einige Strings veränderst, z.B. in der Größe oder halt das ein String gar nicht mehr benötigt wird, dann noch ein Neuer dazu, der den verfügbaren Hauptspeicher überschreiten würde, sofern sich kein überflüssiger String in dem großen Haufen finden würde etc.

Dann hast Du das Gleiche, was in BASIC im relativ kleinen Variablen-Bereich passiert: Fragmentierung, die nach "Aufräumen" schreit.

Das Kuddelmuddel aufzuräumen ist in C dann aber wesentlich aufwändiger, weil der Compiler die tatsächliche Größe des Strings gar nicht kennt.

Er führt kein Buch darüber, was ein BASIC-Interpreter/Compiler hingegen tut.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 22:07 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Aber in C haben doch Strings eine feste länge und müssten deshalb
doch gar nicht "defragmentiert" werden oder?


Nein, Strings haben in C überhaupt keine feste Länge. Üblicherweise werden Strings durch ein 0-byte abgeschlossen, das ist ja auch der Grund, warum Du überall "+CHR$(0)" schreiben musst, wenn Du Basic-Strings an eine Funktion mit C-Konventionen übergeben musst.

In C gibt es keine solchen Funktionen zum Bearbeiten von Strings ala "xyz"+abc$ oder MID$(abc$, x, y). Deshalb gibt es keinen Speichermanager. Das heißt aber noch lange nicht, dass es in C keine Speicherfragmentierung geben könnte.

Zitat:
Original von Ralf27:
Deswegen hatte ich mal ne Funktion für Strings geschrieben, die unabhängig von MB gehaltet werden müssen:
code:
REM Die folgende Funktion brauch ich nur, weil sonst MaxonBasic mir die
REM Namen in den Fenstern versaut, wenn er wiedermal einfach die variablen
REM aufräumt
FUNCTION AllocName&(c$,BYVAL n)STATIC
 SHARED AllocN&()
 IF AllocN&(n)THEN FreeMem AllocN&(n),PEEKW(AllocN&(n)):AllocN&(n)=0
 a$=c$+CHR$(0)
 a&=LEN(a$)+2
 b&=AllocMem&(a&,MEMF_PUBLIC&)
 IF b& THEN
  AllocN&(n)=b&
  POKEW b&,a&
  CopyMem SADD(a$),b&+2,LEN(a$)
 END IF
 AllocName&=b&+2
END FUNCTION



Du solltest AllocVec und FreeVec verwenden. Dann musst Du Dir nicht die Länge selber merken, was effizienter ist, da die OS-Funktionen nunmal in einer performanteren Sprache als Basic geschrieben wurden. Also im Zweifelsfall immer OS-Funktion statt Basic-Code verwenden. Außerdem empfiehlt es sich, das 0-byte Handling nicht über String-Operationen (die nunmal den Basic-Speichermanager beschäftigen) durchzuführen.

code:
REM Die folgende Funktion brauch ich nur, weil sonst MaxonBasic mir die
REM Namen in den Fenstern versaut, wenn er wiedermal einfach die variablen
REM aufräumt
REM Sie gibt 0 im Fehlerfall zurück
FUNCTION AllocName&(c$,BYVAL n)STATIC
  SHARED AllocN&()
  IF AllocN&(n) THEN FreeVec AllocN&(n)
  b&=AllocVec&(LEN(c$)+1, MEMF_PUBLIC&)
  AllocN&(n)=b&
  IF b& THEN
    CopyMem SADD(c$), b&, LEN(c$)
    POKE b&+LEN(c$), 0
  END IF
  AllocName&=b&
END FUNCTION


mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 22:19 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von whose:
Der nicht-dynamische Heap macht übrigens die Garbage Collection gerade notwendig ;)

Unzulässige Verallgemeinerung. Ob dynamisch oder statisch ist in diesem Zusammenhang nicht relevant. Das Mischen von dynamischen und statischen Daten ein ein und demselben Speicherbereich macht gc notwendig.

Zitat:
Im Prinzip machst Du damit aus der statischen String-Verwaltung von BASIC eine mehr oder weniger dynamische auf OS-Basis alá C. Allozieren von Speicher für einen String, so wie es in C der Compiler für einen erledigt.
Die Basic String-Verwaltung ist nicht statisch. Zu jeder beliebigen Zeit neue Strings erzeugen oder wegwerfen zu können, ist sogar hochgradig dynamisch. Und der C-Compiler erledigt das nicht für einen, weil er solche String-Operationen überhaupt gar nicht erst anbietet. Das einzige, was ein C-Compiler kann, ist einen statischen String im Programm abzulegen, und, wenn in einem initializer verwendet, auf den Stack zu kopieren. Schon beim Heap braucht man dafür eine Support-Funktion, weil der C-Compiler das nicht kann.
Zitat:
Das Kuddelmuddel aufzuräumen ist in C dann aber wesentlich aufwändiger, weil der Compiler die tatsächliche Größe des Strings gar nicht kennt.
Die Größe eines Strings könnte der Compiler sehr wohl ermitteln, weil C-Strings durch ein 0-byte abgeschlossen werden. Was viel schwerer wiegt ist die Tatsache, dass der C-Compiler nicht weiß, woher ein String kommt, also welche Allokation zu dem String gehört und ob der String evtl. noch benutzt wird (nicht anders als in Basic: der String könnte z.B. in einem Fenstertitel referenziert werden), also ob der zugehörige Speicher überhaupt freigegeben werden kann.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

07.02.2007, 23:05 Uhr

MaikG
Posts: 5172
Nutzer
>Ja, das ist so ne Sache bei MB. Da hab ich mich auch als drüber
>aufgeregt. Vorallem bei Fenstertitel kann man dann die Aufräumaktion
>des Compilers sehn.

Wie lange hast du gebraucht um herrauszufinden woran das liegt?
Ich meine kein Hinweis in den Beispielen oder im Handbuch.
Ich hab dann immer den Heap erhöht, mit der annahme das Programm
sei zu komplex. Es ging dann auch immer weil man normalerweise
ja nicht mit tausenden Strings handtiert.

>Deswegen hatte ich mal ne Funktion für Strings geschrieben, die
>unabhängig von MB gehaltet werden müssen:

An eine Funktion hab ich auch schon gedacht, dann aber
fauler weise einen einzigen bereich mittels AllocVec geholt
und die Strings nacheineinder da rein geschoben.
Die Positon der einzelnen Strings habe ich mittels Konstanten
festgelgt. Ist ggf. dann mal einfacher wenn man eine andere
Sprache unterstützen will etc.


>Die Strings selbst nicht, nein. Aber stell Dir doch mal vor, was mit
>dem Hauptspeicher passiert, wenn Du den bis zum Bersten mit Strings
>vollstopfst und dann einige Strings veränderst, z.B. in der Größe
>oder halt das ein String gar nicht mehr benötigt wird, dann noch
>ein Neuer dazu, der den verfügbaren Hauptspeicher überschreiten
>würde, sofern sich kein überflüssiger String in dem großen Haufen
>finden würde etc.

Naja gut meine Strings$ sind ja eine Sache aber MBasic behandelt
ja alles was in " " steht schon als String. Das ist ja nur zu
übergabe und kann sofort wieder weg. Da es aber nicht so ist muss
es ja zwangsweise zum Heap-voll kommen


>In C gibt es keine solchen Funktionen zum Bearbeiten von Strings
>ala "xyz"+abc$ oder MID$(abc$, x, y). Deshalb gibt es keinen
>Speichermanager. Das heißt aber noch lange nicht, dass es in C
>keine Speicherfragmentierung geben könnte.

Ja, Mid$ und so vermisse ich auch bei C...


Okay, hab jetzt alles im Programm angepasst.
Danke @All

[ - Antworten - Zitieren - Direktlink - ]

08.02.2007, 00:01 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von MaikG:
>Die Strings selbst nicht, nein. Aber stell Dir doch mal vor, was mit
>dem Hauptspeicher passiert, wenn Du den bis zum Bersten mit Strings
>vollstopfst und dann einige Strings veränderst, z.B. in der Größe
>oder halt das ein String gar nicht mehr benötigt wird, dann noch
>ein Neuer dazu, der den verfügbaren Hauptspeicher überschreiten
>würde, sofern sich kein überflüssiger String in dem großen Haufen
>finden würde etc.

Naja gut meine Strings$ sind ja eine Sache aber MBasic behandelt
ja alles was in " " steht schon als String. Das ist ja nur zu
übergabe und kann sofort wieder weg. Da es aber nicht so ist muss
es ja zwangsweise zum Heap-voll kommen


Nicht nur MBasic behandelt alles in "" als String. Überleg doch mal, wie ein C-Compiler wohl vorgehen würde, wenn Du eine String-Konstante definierst. Auf diese darf ja per definitionem lesend zugegriffen werden, nur nicht schreibend und zum Zeitpunkt ihrer Deklaration ist die weitere Verwendung gar nicht bekannt.

Was macht ein C-Compiler damit wohl? Er schiebt sie vorläufig auf den Heap, so wie es ein BASIC-Compilerer auch macht. Ein BASIC-Compiler weiß, daß er die Konstante ggf. nur ein Mal verwendet, weswegen die GC auch nicht wegen der String-Konstanten auftritt bei diesem (beim Interpreter schon).

Wegen temporärer Strings tritt die GC aber auf, was z.B. gern bei String-Additionen wie z.B. String-Konstante + STR$ passiert.

Der Unterschied zu C besteht in der Behandlung "dynamischer" Strings, von denen C so gut wie gar keine Ahnung hat. Strings im BASIC-Sinn gibt es in C gar nicht! Weder statisch noch dynamisch. Da gibt es nur Arrays von char, die einen Start besitzen, aber kein bekanntes Ende.

Ohne die C-Standardbibliothek müßte sich ein C-Programmierer auch jedes Mal eine Bombe bauen, um mit Strings und deren Folgen umzugehen :D

Zitat:
>In C gibt es keine solchen Funktionen zum Bearbeiten von Strings
>ala "xyz"+abc$ oder MID$(abc$, x, y). Deshalb gibt es keinen
>Speichermanager. Das heißt aber noch lange nicht, dass es in C
>keine Speicherfragmentierung geben könnte.

Ja, Mid$ und so vermisse ich auch bei C...


Ist sehr praktisch, oder? In C gibt es sowas ähnliches zwar auch, ist aber ungleich aufwändiger zu implementieren, weil man bei einem C-String immer nach dem Ende suchen muß. Dem BASIC-Interpreter ist die Größe eines Strings immer bekannt, da ist MID$ z.B. nur eine simple Division/Addition-Operation.

Zitat:
Okay, hab jetzt alles im Programm angepasst.
Danke @All


Das und das es funktioniert ist die Hauptsache. Du kommst aber auch immer mit Sachen um die Ecke... ;)

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

08.02.2007, 19:54 Uhr

Ralf27
Posts: 2779
Nutzer
Zitat:
Original von MaikG:
Wie lange hast du gebraucht um herrauszufinden woran das liegt?
Ich meine kein Hinweis in den Beispielen oder im Handbuch.
Ich hab dann immer den Heap erhöht, mit der annahme das Programm
sei zu komplex. Es ging dann auch immer weil man normalerweise
ja nicht mit tausenden Strings handtiert.


Nun, ich hab den Fehler gesehn (z.b. Fenstertitel ändert sich ohne das er es tun sollte, bzw. seh ich dann ein Teil von anderen Strings, etc.) und hatte dann auch mal hier im Forum einen interesanten Thread zu MBasic und Strings. Da ging es auch um die GC, die mich fast zum erzweifeln gebracht hätte (unerklärliche Fehler, etc.)

Im Handbuch wirst du wahrscheinlich auch nicht die zur Drucklegung wohl unbekannten Bugs finden. Und der Compiler hat so einige Probleme, die man zwar umschiffen kann... Nunja, leider wird ja der Compiler nicht weiterentwickelt, was ja auch verständlich ist.

Ich finde es auch schade das der Compiler wohl nur 68000er Code liefert und das dieser wirklich auch recht langsam ist. Sogar ACE, der freie Basiccompiler ist schneller wenn es um Integer geht. Aber bei Basicprogrammen sollte man möglichst immer auf Integer setzen, sonst wird es wirklich langsam...
--
http://www.alternativercomputerclub.de.vu

[ - Antworten - Zitieren - Direktlink - ]

08.02.2007, 20:25 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von whose:
Was macht ein C-Compiler damit wohl? Er schiebt sie vorläufig auf den Heap, so wie es ein BASIC-Compilerer auch macht.

Eigentlich belässt er sie in der Daten-Sektion des Programms. Es sei denn, Du benutzt sie, um ein lokales char-array damit zu initialisieren, dann werden die Daten auf den Stack kopiert. Aber bei bei Strings ala char* foo="bar"; werden überhaupt keine Daten kopiert oder verschoben, weswegen man den String eigentlich als const deklarieren müsste, was gerade ältere Compiler gerne ignorieren, neuere aber anmeckern, wenn man die entspr. Warning eingeschaltet lässt.

Auf den Heap kopieren muss dagegen der Programmierer immer selbst, weil es die entsprechende Konstruktion ala new char[], die das automatisch machen könnte, in der Programmiersprache C nicht gibt.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

09.02.2007, 00:15 Uhr

MaikG
Posts: 5172
Nutzer

>Nun, ich hab den Fehler gesehn (z.b. Fenstertitel ändert sich ohne
>das er es tun sollte, bzw. seh ich dann ein Teil von anderen
>Strings, etc.) und hatte dann auch mal hier im Forum einen
>interesanten Thread zu MBasic und Strings.

Hier hab ich gar nicht gesucht, weil wir ja die einzigen sind
die wirklich noch Aktiv in MB Programmieren...


>Im Handbuch wirst du wahrscheinlich auch nicht die zur Drucklegung
>wohl unbekannten Bugs finden. Und der Compiler hat so einige
>Probleme, die man zwar umschiffen kann... Nunja, leider wird ja der
>Compiler nicht weiterentwickelt, was ja auch verständlich ist.

Kennst du noch schlimme bevor ich wieder nach fehlern meinerseits
suche?

Mit der Lines angabe war klar, wobei alle Fehler in letzter
Zeit waren Zeilen genau und das Prog ist >1900 Zeilen lang ohne
Includes.
Ansonsten sind manche Compiler-prüf-optionen langsam auf 040/060 und
MB Fenster auf CGX sind beim Text-Scrollen lahm.

[ - Antworten - Zitieren - Direktlink - ]

09.02.2007, 09:11 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von Holger:
Zitat:
Original von whose:
Was macht ein C-Compiler damit wohl? Er schiebt sie vorläufig auf den Heap, so wie es ein BASIC-Compilerer auch macht.

Eigentlich belässt er sie in der Daten-Sektion des Programms. Es sei denn, Du benutzt sie, um ein lokales char-array damit zu initialisieren, dann werden die Daten auf den Stack kopiert.


Naja, ich habe mich da Maik angepaßt. Ein BASIC-Interpreter/Compiler kennt normalerweise auch keinen Heap im herkömmlichen Sinn. Die haben einen Variablen-Bereich, der meist nicht einmal dynamisch verwaltet wird.

Zitat:
Aber bei bei Strings ala char* foo="bar"; werden überhaupt keine Daten kopiert oder verschoben, weswegen man den String eigentlich als const deklarieren müsste, was gerade ältere Compiler gerne ignorieren, neuere aber anmeckern, wenn man die entspr. Warning eingeschaltet lässt.

Mal abgesehen davon, daß ich so etwas kaum mache (gerade, wenn man viel mit OS-Funktionen hantiert, werden String-Konstanten reichlich lästig), der Hinweis ist wertvoll :)

Zitat:
Auf den Heap kopieren muss dagegen der Programmierer immer selbst, weil es die entsprechende Konstruktion ala new char[], die das automatisch machen könnte, in der Programmiersprache C nicht gibt.

Naja, es gibt sicher Linkerbibliotheken (abseits der Standardbibliothek), die diese Aufgabe übernehmen würden, sofern man diese Bibliotheken einsetzt.

Wie ich oben schon sagte, habe ich den Ausdruck Heap mit Rücksicht auf Maik eingesetzt.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]


-1- 2 [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > Garbage Collections umgehen [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.