AllocateMemory() zu klein » Warum geht das hier?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

AllocateMemory() zu klein » Warum geht das hier?

Beitrag 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... :wink:

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? :)
Zuletzt geändert von AND51 am 05.04.2007 18:15, insgesamt 1-mal geändert.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Beitrag von RSBasic »

@AND51
Kannst du kein besseren Titel finden?
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Einen passenderen Titel gibt's nicht. Ich will ja gerade das WARUM wissen. Aber ok, ich schreib noch AllocateMemory() dazu...
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag 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 :mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag 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.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag 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 :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

> Speicherbereich *p1 und *p2 müssen aber nicht auf einander Folgen.
Meeeeehr, das sind genau die Informationen, die ich haben will :D
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?
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Thalius
Beiträge: 476
Registriert: 17.02.2005 16:17
Wohnort: Basel / Schweiz

Beitrag 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
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag 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.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag 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 ...
Antworten