Seite 1 von 3
AllocateMemory() zu klein » Warum geht das hier?
Verfasst: 05.04.2007 17:47
von AND51
Hallo!
Ich habe eine Frage. Ich reserveire nur ein Byte Speicher, kann aber trotzdem ROmane reinschreiben. Warum?
Code: Alles auswählen
*buffer=AllocateMemory(1)
PokeS(*buffer, "Zu lang")
Debug PeekS(*buffer)
Kein invalider, kein Programm oder gar PC Crash... So'n Spielverderber...
Ich wollte eigentlich eine Routine schreiben, die einen empfangenen String automatisch in einen Buffer schreibt, so hole ich die Daten ja immer ab:
Code: Alles auswählen
Repeat : Until ReceiveNetworkData(Connection, *buffer, 1000) <> 1000
Nun möchte ich in die Repeat-Schleife eine If-Abfrage einbauen, die den Buffer nachträglich mit
ReAllocateMemory() und
MemorySize() und
MemoryStringlength() vergrößert, falls erforderlich.
Da ich den oben beschriebenen Effekt festgestellt habe, stelle ich mir die Frage, ob ich das wirklich brauche.
Das da oben ist garantiert rational erklärbar, aber das frage ich ja euch. Nicht dass ich mich immer darauf verlasse und später im Programm, wenn es vereintlicherweise fertig ist, taucht dieser beknackte Fehler auf.
Könnt ihr mir helfen und mal eure Erklärungswut rauslassen?

Verfasst: 05.04.2007 18:14
von RSBasic
@AND51
Kannst du kein besseren Titel finden?
Verfasst: 05.04.2007 18:15
von AND51
Einen passenderen Titel gibt's nicht. Ich will ja gerade das WARUM wissen. Aber ok, ich schreib noch AllocateMemory() dazu...
Verfasst: 05.04.2007 18:23
von ts-soft
Fehlerhafter Code führt nicht unbedingt zu einem Nichtfunktionieren,
jedenfalls nicht bei so kurzen Beispielen. In einem richtigen Programm wird
es wohl über kurz oder lang zu IMA führen

Verfasst: 05.04.2007 18:56
von AND51
Dann ist der 1. Code also falsch... Gut!
Kannst du mir denn helfen, einen sich selbst vergrößendern Epfangsbuffer zu schreiben?
Das hier sieht doch schon mal gut aus:
Code: Alles auswählen
Define *buffer=AllocateMemory(4)
Repeat
If MemorySize(*buffer)-MemoryStringLength(*buffer) < 1000
Define *neu_buffer=ReAllocateMemory(*buffer, MemorySize(*buffer)+1000)
If *neu_buffer
*buffer=*neu_buffer
Else
Break
EndIf
EndIf
Until ReceiveNetworkData(ConnectionID, *buffer, 1000) <> 1000
Ich weiß nur nicht was ich machen soll, wenn das Vergrößern fehl schlägt. Hängt vom Projekt ab, ob das Programm dann mit den jetzigen Daten weiterrechnen oder abbrechen soll.
Sagen wir einfach, er soll mit den Daten, die er schon hat weiterarbeiten.
Verfasst: 05.04.2007 18:56
von mk-soft
Windows verteilt blockweise den Arbeitsspeicher.
Code: Alles auswählen
*p1 = AllocateMemory(1)
*p2 = AllocateMemory(1)
Debug *p1
Debug *p2
Debug *p2 - *p1
PokeS(*p1, "Hallo Welt, Hallo Welt, ")
Debug PeekS(*p1)
Debug PeekS(*p2)
Speicherbereich *p1 und *p2 müssen aber nicht auf einander Folgen.
Ein zu kleiner Speicherbereich führt irgendwann immer zu einen IMA
FF

Verfasst: 05.04.2007 19:03
von AND51
> Speicherbereich *p1 und *p2 müssen aber nicht auf einander Folgen.
Meeeeehr, das sind genau die Informationen, die ich haben will
Gut, das schon mal zu wissen.
Ich könnte oben statt bei 4 auch bei 4096 oder so anfangen, ist mir egal. Nur das Verfahren, ist das richtig?
Verfasst: 06.04.2007 16:21
von Thalius
Apropos ich rate dir von dynamischer reallocierung in ner schleife ab - ist ein riesen Performance hog. Nimm lieber einen mittleren ( je nachdem was für daten du sendest / empfängst ) Buffer und stückel dir notfalls zu grosse Pakete zusammen ( wobei du jeden Part auch wieder CRC-en kannst ).
Speziell übers Internet macht das mehr Sinn.
Thalius
Verfasst: 06.04.2007 20:05
von AND51
> Apropos ich rate dir von dynamischer reallocierung in ner schleife ab
Aber was soll ich denn machen, wenn ich die Datenmenge vorher nicht kenne? Beispielsweise, wenn ich einen HTTP-Server programmiere und der Client macht einen Upload, dann weiß ich die Datenmenge vorher ja gar nicht.
Für kleine SPiele etc. hast du Recht. Da bestimme ich ja von vornherein die maximalste Datenmenge, da ich ja dann der bin, der CLient und Server programmiert.
Verfasst: 06.04.2007 20:54
von edel
Kannst du auch so machen, alloziere den Speicher aber im voraus.
Wenn du pro Schleifendurchgang 1 Byte empfaengst , nimmst du
einen Speicherblock von 10 Bytes, sind die 10 voll, packst du weiter
10 dazu usw ...